├── .gitignore ├── README.md ├── _build ├── build.config.php ├── build.map.php ├── build.transport.php ├── data │ ├── transport.chunks.php │ ├── transport.plugins.php │ ├── transport.settings.php │ └── transport.snippets.php ├── includes │ └── functions.php ├── properties │ ├── properties.haprofile.php │ └── properties.hybridauth.php └── resolvers │ └── resolve.tables.php ├── assets └── components │ └── hybridauth │ ├── connector.php │ ├── css │ ├── mgr │ │ ├── bootstrap.buttons.css │ │ └── main.css │ └── web │ │ └── default.css │ ├── img │ └── web │ │ ├── color-icons.png │ │ └── grayscale-icons.png │ └── js │ └── mgr │ ├── hybridauth.js │ ├── misc │ └── utils.js │ └── widgets │ └── service.grid.js └── core └── components └── hybridauth ├── composer.json ├── docs ├── changelog.txt ├── license.txt └── readme.txt ├── elements ├── chunks │ ├── chunk.login.tpl │ ├── chunk.logout.tpl │ ├── chunk.profile.tpl │ ├── chunk.provider.tpl │ └── chunk.provider_active.tpl ├── plugins │ └── plugin.hybridauth.php └── snippets │ ├── snippet.haprofile.php │ └── snippet.hybridauth.php ├── lexicon ├── en │ ├── default.inc.php │ └── properties.inc.php ├── ru │ ├── default.inc.php │ └── properties.inc.php └── uk │ ├── default.inc.php │ └── properties.inc.php ├── model ├── hybridauth │ ├── hauserservice.class.php │ ├── hybridauth.class.php │ ├── metadata.mysql.php │ └── mysql │ │ ├── hauserservice.class.php │ │ └── hauserservice.map.inc.php └── schema │ └── hybridauth.mysql.schema.xml ├── processors ├── mgr │ └── service │ │ ├── getlist.class.php │ │ └── remove.class.php └── web │ ├── service │ ├── create.class.php │ ├── remove.class.php │ └── update.class.php │ └── user │ ├── create.class.php │ └── update.class.php └── providers ├── ModxPro.php └── Yandex.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | .DS_Store 4 | config.core.php 5 | /core/components/hybridauth/vendor/ 6 | /core/components/hybridauth/composer.lock 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## HybridAuth for MODX Revolution 2 | 3 | Component for login through 3rd party services. 4 | 5 | ## HybridAuth 6 | 7 | HybridAuth enables developers to easily build social applications and tools 8 | to engage websites vistors and customers on a social level by implementing 9 | social sign-in, social sharing, users profiles, friends list, activities 10 | stream, status updates and more. 11 | 12 | The main goal of HybridAuth is to act as an abstract API between your application 13 | and various social apis and identities providers such as Facebook, Twitter, 14 | MySpace and Google. 15 | 16 | ## Repository 17 | 18 | HybridAuth repository is made up of several projects: 19 | 20 | - **HybridAuth Core library** includes OpenID, Facebook, Twitter, LinkedIn, 21 | MySpace, Google, Yahoo, Windows Live, Foursquare and AOL. 22 | - **The additional providers project** contains many others services 23 | which you may want to use, 24 | - **Examples and demos** contains five working examples for you to test, 25 | 26 | ## Getting Started 27 | 28 | We highly recommend that you download and use the latest release from HybridAuth website 29 | at [http://hybridauth.sourceforge.net/download.html](http://hybridauth.sourceforge.net/download.html) 30 | 31 | You can find complete documentation for HybridAuth 32 | at [http://hybridauth.sourceforge.net](http://hybridauth.sourceforge.net) 33 | 34 | -------------------------------------------------------------------------------- /_build/build.config.php: -------------------------------------------------------------------------------- 1 | $root, 11 | 'build' => $root . '_build/', 12 | 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER, 13 | 'model' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/', 14 | 'schema' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/schema/', 15 | 'xml' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/schema/' . PKG_NAME_LOWER . '.mysql.schema.xml', 16 | ); 17 | unset($root); 18 | 19 | require MODX_CORE_PATH . 'model/modx/modx.class.php'; 20 | require $sources['build'] . '/includes/functions.php'; 21 | 22 | $modx = new modX(); 23 | $modx->initialize('mgr'); 24 | $modx->getService('error', 'error.modError'); 25 | $modx->setLogLevel(modX::LOG_LEVEL_INFO); 26 | $modx->setLogTarget('ECHO'); 27 | $modx->loadClass('transport.modPackageBuilder', '', false, true); 28 | if (!XPDO_CLI_MODE) { 29 | echo '
';
30 | }
31 | 
32 | /** @var xPDOManager $manager */
33 | $manager = $modx->getManager();
34 | /** @var xPDOGenerator $generator */
35 | $generator = $manager->getGenerator();
36 | 
37 | // Remove old model
38 | removeDir($sources['model'] . PKG_NAME_LOWER . '/mysql');
39 | 
40 | // Generate a new one
41 | $generator->parseSchema($sources['xml'], $sources['model']);
42 | 
43 | $modx->log(modX::LOG_LEVEL_INFO, 'Model generated.');
44 | if (!XPDO_CLI_MODE) {
45 |     echo '
'; 46 | } 47 | -------------------------------------------------------------------------------- /_build/build.transport.php: -------------------------------------------------------------------------------- 1 | $root, 15 | 'build' => $root . '_build/', 16 | 'data' => $root . '_build/data/', 17 | 'resolvers' => $root . '_build/resolvers/', 18 | 'chunks' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/', 19 | 'snippets' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/', 20 | 'plugins' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/plugins/', 21 | 'lexicon' => $root . 'core/components/' . PKG_NAME_LOWER . '/lexicon/', 22 | 'docs' => $root . 'core/components/' . PKG_NAME_LOWER . '/docs/', 23 | 'pages' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/pages/', 24 | 'source_assets' => $root . 'assets/components/' . PKG_NAME_LOWER, 25 | 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER, 26 | ); 27 | unset($root); 28 | 29 | require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; 30 | require_once $sources['build'] . '/includes/functions.php'; 31 | 32 | $modx = new modX(); 33 | $modx->initialize('mgr'); 34 | echo '
'; /* used for nice formatting of log messages */
 35 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
 36 | $modx->setLogTarget('ECHO');
 37 | $modx->getService('error', 'error.modError');
 38 | 
 39 | $modx->loadClass('transport.modPackageBuilder', '', false, true);
 40 | $builder = new modPackageBuilder($modx);
 41 | $builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE);
 42 | $builder->registerNamespace(PKG_NAME_LOWER, false, true, '{core_path}components/' . PKG_NAME_LOWER . '/');
 43 | $modx->log(modX::LOG_LEVEL_INFO, 'Created Transport Package and Namespace.');
 44 | 
 45 | /* load system settings */
 46 | if (defined('BUILD_SETTING_UPDATE')) {
 47 |     $settings = include $sources['data'] . 'transport.settings.php';
 48 |     if (!is_array($settings)) {
 49 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.');
 50 |     } else {
 51 |         $attributes = array(
 52 |             xPDOTransport::UNIQUE_KEY => 'key',
 53 |             xPDOTransport::PRESERVE_KEYS => true,
 54 |             xPDOTransport::UPDATE_OBJECT => BUILD_SETTING_UPDATE,
 55 |         );
 56 |         foreach ($settings as $setting) {
 57 |             $vehicle = $builder->createVehicle($setting, $attributes);
 58 |             $builder->putVehicle($vehicle);
 59 |         }
 60 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($settings) . ' System Settings.');
 61 |     }
 62 |     unset($settings, $setting, $attributes);
 63 | }
 64 | 
 65 | /* load plugins events */
 66 | if (defined('BUILD_EVENT_UPDATE')) {
 67 |     $events = include $sources['data'] . 'transport.events.php';
 68 |     if (!is_array($events)) {
 69 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in events.');
 70 |     } else {
 71 |         $attributes = array(
 72 |             xPDOTransport::PRESERVE_KEYS => true,
 73 |             xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE,
 74 |         );
 75 |         foreach ($events as $event) {
 76 |             $vehicle = $builder->createVehicle($event, $attributes);
 77 |             $builder->putVehicle($vehicle);
 78 |         }
 79 |         $modx->log(xPDO::LOG_LEVEL_INFO, 'Packaged in ' . count($events) . ' Plugins events.');
 80 |     }
 81 |     unset ($events, $event, $attributes);
 82 | }
 83 | 
 84 | /* package in default access policy */
 85 | if (defined('BUILD_POLICY_UPDATE')) {
 86 |     $attributes = array(
 87 |         xPDOTransport::PRESERVE_KEYS => false,
 88 |         xPDOTransport::UNIQUE_KEY => array('name'),
 89 |         xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_UPDATE,
 90 |     );
 91 |     $policies = include $sources['data'] . 'transport.policies.php';
 92 |     if (!is_array($policies)) {
 93 |         $modx->log(modX::LOG_LEVEL_FATAL, 'Adding policies failed.');
 94 |     }
 95 |     foreach ($policies as $policy) {
 96 |         $vehicle = $builder->createVehicle($policy, $attributes);
 97 |         $builder->putVehicle($vehicle);
 98 |     }
 99 |     $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($policies) . ' Access Policies.');
100 |     flush();
101 |     unset($policies, $policy, $attributes);
102 | }
103 | 
104 | /* package in default access policy templates */
105 | if (defined('BUILD_POLICY_TEMPLATE_UPDATE')) {
106 |     $templates = include dirname(__FILE__) . '/data/transport.policytemplates.php';
107 |     $attributes = array(
108 |         xPDOTransport::PRESERVE_KEYS => false,
109 |         xPDOTransport::UNIQUE_KEY => array('name'),
110 |         xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_TEMPLATE_UPDATE,
111 |         xPDOTransport::RELATED_OBJECTS => true,
112 |         xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
113 |             'Permissions' => array(
114 |                 xPDOTransport::PRESERVE_KEYS => false,
115 |                 xPDOTransport::UPDATE_OBJECT => BUILD_PERMISSION_UPDATE,
116 |                 xPDOTransport::UNIQUE_KEY => array('template', 'name'),
117 |             ),
118 |         ),
119 |     );
120 |     if (is_array($templates)) {
121 |         foreach ($templates as $template) {
122 |             $vehicle = $builder->createVehicle($template, $attributes);
123 |             $builder->putVehicle($vehicle);
124 |         }
125 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($templates) . ' Access Policy Templates.');
126 |         flush();
127 |     } else {
128 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in Access Policy Templates.');
129 |     }
130 |     unset($templates, $template, $attributes);
131 | }
132 | 
133 | /* load menus */
134 | if (defined('BUILD_MENU_UPDATE')) {
135 |     $menus = include $sources['data'] . 'transport.menu.php';
136 |     $attributes = array(
137 |         xPDOTransport::PRESERVE_KEYS => true,
138 |         xPDOTransport::UPDATE_OBJECT => BUILD_MENU_UPDATE,
139 |         xPDOTransport::UNIQUE_KEY => 'text',
140 |         xPDOTransport::RELATED_OBJECTS => true,
141 |         xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
142 |             'Action' => array(
143 |                 xPDOTransport::PRESERVE_KEYS => false,
144 |                 xPDOTransport::UPDATE_OBJECT => BUILD_ACTION_UPDATE,
145 |                 xPDOTransport::UNIQUE_KEY => array('namespace', 'controller'),
146 |             ),
147 |         ),
148 |     );
149 |     if (is_array($menus)) {
150 |         foreach ($menus as $menu) {
151 |             $vehicle = $builder->createVehicle($menu, $attributes);
152 |             $builder->putVehicle($vehicle);
153 |             /** @var modMenu $menu */
154 |             $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in menu "' . $menu->get('text') . '".');
155 |         }
156 |     } else {
157 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in menu.');
158 |     }
159 |     unset($vehicle, $menus, $menu, $attributes);
160 | }
161 | 
162 | 
163 | /* create category */
164 | $modx->log(xPDO::LOG_LEVEL_INFO, 'Created category.');
165 | /** @var modCategory $category */
166 | $category = $modx->newObject('modCategory');
167 | $category->set('category', PKG_NAME);
168 | /* create category vehicle */
169 | $attr = array(
170 |     xPDOTransport::UNIQUE_KEY => 'category',
171 |     xPDOTransport::PRESERVE_KEYS => false,
172 |     xPDOTransport::UPDATE_OBJECT => true,
173 |     xPDOTransport::RELATED_OBJECTS => true,
174 | );
175 | 
176 | /* add snippets */
177 | if (defined('BUILD_SNIPPET_UPDATE')) {
178 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Snippets'] = array(
179 |         xPDOTransport::PRESERVE_KEYS => false,
180 |         xPDOTransport::UPDATE_OBJECT => BUILD_SNIPPET_UPDATE,
181 |         xPDOTransport::UNIQUE_KEY => 'name',
182 |     );
183 |     $snippets = include $sources['data'] . 'transport.snippets.php';
184 |     if (!is_array($snippets)) {
185 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.');
186 |     } else {
187 |         $category->addMany($snippets);
188 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($snippets) . ' snippets.');
189 |     }
190 | }
191 | 
192 | /* add chunks */
193 | if (defined('BUILD_CHUNK_UPDATE')) {
194 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Chunks'] = array(
195 |         xPDOTransport::PRESERVE_KEYS => false,
196 |         xPDOTransport::UPDATE_OBJECT => BUILD_CHUNK_UPDATE,
197 |         xPDOTransport::UNIQUE_KEY => 'name',
198 |     );
199 |     $chunks = include $sources['data'] . 'transport.chunks.php';
200 |     if (!is_array($chunks)) {
201 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in chunks.');
202 |     } else {
203 |         $category->addMany($chunks);
204 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($chunks) . ' chunks.');
205 |     }
206 | }
207 | 
208 | /* add plugins */
209 | if (defined('BUILD_PLUGIN_UPDATE')) {
210 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = array(
211 |         xPDOTransport::PRESERVE_KEYS => false,
212 |         xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE,
213 |         xPDOTransport::UNIQUE_KEY => 'name',
214 |     );
215 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['PluginEvents'] = array(
216 |         xPDOTransport::PRESERVE_KEYS => true,
217 |         xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE,
218 |         xPDOTransport::UNIQUE_KEY => array('pluginid', 'event'),
219 |     );
220 |     $plugins = include $sources['data'] . 'transport.plugins.php';
221 |     if (!is_array($plugins)) {
222 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in plugins.');
223 |     } else {
224 |         $category->addMany($plugins);
225 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($plugins) . ' plugins.');
226 |     }
227 | }
228 | 
229 | $vehicle = $builder->createVehicle($category, $attr);
230 | 
231 | /* now pack in resolvers */
232 | $vehicle->resolve('file', array(
233 |     'source' => $sources['source_assets'],
234 |     'target' => "return MODX_ASSETS_PATH . 'components/';",
235 | ));
236 | $vehicle->resolve('file', array(
237 |     'source' => $sources['source_core'],
238 |     'target' => "return MODX_CORE_PATH . 'components/';",
239 | ));
240 | 
241 | foreach ($BUILD_RESOLVERS as $resolver) {
242 |     if ($vehicle->resolve('php', array('source' => $sources['resolvers'] . 'resolve.' . $resolver . '.php'))) {
243 |         $modx->log(modX::LOG_LEVEL_INFO, 'Added resolver "' . $resolver . '" to category.');
244 |     } else {
245 |         $modx->log(modX::LOG_LEVEL_INFO, 'Could not add resolver "' . $resolver . '" to category.');
246 |     }
247 | }
248 | 
249 | flush();
250 | $builder->putVehicle($vehicle);
251 | 
252 | /* now pack in the license file, readme and setup options */
253 | $builder->setPackageAttributes(array(
254 |     'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'),
255 |     'license' => file_get_contents($sources['docs'] . 'license.txt'),
256 |     'readme' => file_get_contents($sources['docs'] . 'readme.txt'),
257 |     /*
258 |     'setup-options' => array(
259 |         'source' => $sources['build'].'setup.options.php',
260 |     ),
261 |     */
262 | ));
263 | $modx->log(modX::LOG_LEVEL_INFO, 'Added package attributes and setup options.');
264 | 
265 | /* zip up package */
266 | $modx->log(modX::LOG_LEVEL_INFO, 'Packing up transport package zip...');
267 | $builder->pack();
268 | 
269 | $mtime = microtime();
270 | $mtime = explode(" ", $mtime);
271 | $mtime = $mtime[1] + $mtime[0];
272 | $tend = $mtime;
273 | $totalTime = ($tend - $tstart);
274 | $totalTime = sprintf("%2.4f s", $totalTime);
275 | 
276 | $signature = $builder->getSignature();
277 | if (defined('PKG_AUTO_INSTALL') && PKG_AUTO_INSTALL) {
278 |     $sig = explode('-', $signature);
279 |     $versionSignature = explode('.', $sig[1]);
280 | 
281 |     /** @var modTransportPackage $package */
282 |     if (!$package = $modx->getObject('transport.modTransportPackage', array('signature' => $signature))) {
283 |         $package = $modx->newObject('transport.modTransportPackage');
284 |         $package->set('signature', $signature);
285 |         $package->fromArray(array(
286 |             'created' => date('Y-m-d h:i:s'),
287 |             'updated' => null,
288 |             'state' => 1,
289 |             'workspace' => 1,
290 |             'provider' => 0,
291 |             'source' => $signature . '.transport.zip',
292 |             'package_name' => PKG_NAME,
293 |             'version_major' => $versionSignature[0],
294 |             'version_minor' => !empty($versionSignature[1]) ? $versionSignature[1] : 0,
295 |             'version_patch' => !empty($versionSignature[2]) ? $versionSignature[2] : 0,
296 |         ));
297 |         if (!empty($sig[2])) {
298 |             $r = preg_split('/([0-9]+)/', $sig[2], -1, PREG_SPLIT_DELIM_CAPTURE);
299 |             if (is_array($r) && !empty($r)) {
300 |                 $package->set('release', $r[0]);
301 |                 $package->set('release_index', ($r[1] ?? '0'));
302 |             } else {
303 |                 $package->set('release', $sig[2]);
304 |             }
305 |         }
306 |         $package->save();
307 |     }
308 | 
309 |     if ($package->install()) {
310 |         $modx->runProcessor('system/clearcache');
311 |     }
312 | }
313 | if (!empty($_GET['download'])) {
314 |     echo '';
315 | }
316 | 
317 | $modx->log(modX::LOG_LEVEL_INFO, "\n
Execution time: {$totalTime}\n"); 318 | echo '
'; 319 | -------------------------------------------------------------------------------- /_build/data/transport.chunks.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'file' => 'login', 8 | 'description' => 'Chunk for guest', 9 | ), 10 | 'tpl.HybridAuth.logout' => array( 11 | 'file' => 'logout', 12 | 'description' => 'Chunk for logged in', 13 | ), 14 | 'tpl.HybridAuth.profile' => array( 15 | 'file' => 'profile', 16 | 'description' => 'Chunk for profile update', 17 | ), 18 | 'tpl.HybridAuth.provider' => array( 19 | 'file' => 'provider', 20 | 'description' => 'Chunk for authorization provider', 21 | ), 22 | 'tpl.HybridAuth.provider.active' => array( 23 | 'file' => 'provider_active', 24 | 'description' => 'Chunk for active authorization provider', 25 | ), 26 | ); 27 | 28 | foreach ($tmp as $k => $v) { 29 | /** @var modChunk $chunk */ 30 | /** @var modX $modx */ 31 | /** @var array $sources */ 32 | $chunk = $modx->newObject('modChunk'); 33 | $chunk->fromArray(array( 34 | 'id' => 0, 35 | 'name' => $k, 36 | 'description' => @$v['description'], 37 | 'snippet' => file_get_contents($sources['source_core'] . '/elements/chunks/chunk.' . $v['file'] . '.tpl'), 38 | 'static' => BUILD_CHUNK_STATIC, 39 | 'source' => 1, 40 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/chunk.' . $v['file'] . '.tpl', 41 | ), '', true, true); 42 | 43 | $chunks[] = $chunk; 44 | } 45 | 46 | unset($tmp); 47 | return $chunks; 48 | -------------------------------------------------------------------------------- /_build/data/transport.plugins.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'file' => 'hybridauth', 8 | 'description' => '', 9 | 'events' => array( 10 | 'OnHandleRequest' => array( 11 | 'priority' => 10, 12 | ), 13 | 'OnUserFormPrerender' => array(), 14 | 'OnWebAuthentication' => array(), 15 | ), 16 | ), 17 | ); 18 | 19 | foreach ($tmp as $k => $v) { 20 | /** @var modPlugin $plugin */ 21 | /** @var modX $modx */ 22 | /** @var array $sources */ 23 | $plugin = $modx->newObject('modPlugin'); 24 | $plugin->fromArray(array( 25 | 'id' => 0, 26 | 'name' => $k, 27 | 'category' => 0, 28 | 'description' => @$v['description'], 29 | 'plugincode' => getSnippetContent($sources['source_core'] . '/elements/plugins/plugin.' . $v['file'] . '.php'), 30 | 'static' => BUILD_PLUGIN_STATIC, 31 | 'source' => 1, 32 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/plugins/plugin.' . $v['file'] . '.php', 33 | ), '', true, true); 34 | 35 | $events = array(); 36 | if (!empty($v['events'])) { 37 | foreach ($v['events'] as $k2 => $v2) { 38 | /** @var modPluginEvent $event */ 39 | $event = $modx->newObject('modPluginEvent'); 40 | $event->fromArray(array_merge( 41 | array( 42 | 'event' => $k2, 43 | 'priority' => 0, 44 | 'propertyset' => 0, 45 | ), $v2) 46 | , '', true, true); 47 | $events[] = $event; 48 | } 49 | unset($v['events']); 50 | } 51 | 52 | if (!empty($events)) { 53 | $plugin->addMany($events); 54 | } 55 | 56 | $plugins[] = $plugin; 57 | } 58 | 59 | unset($tmp, $properties); 60 | return $plugins; 61 | -------------------------------------------------------------------------------- /_build/data/transport.settings.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'xtype' => 'textfield', 8 | 'value' => '{"keys":{"id":"12345","secret":"12345"}}', 9 | 'area' => 'ha.keys', 10 | ), 11 | 'keys.GitHub' => array( 12 | 'xtype' => 'textfield', 13 | 'value' => '{"keys":{"id":"12345","secret":"12345"},"scope":"user:email"}', 14 | 'area' => 'ha.keys', 15 | ), 16 | 'keys.Google' => array( 17 | 'xtype' => 'textfield', 18 | 'value' => '{"keys":{"id":"12345","secret":"12345"},"scope":"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"}', 19 | 'area' => 'ha.keys', 20 | ), 21 | 'keys.Facebook' => array( 22 | 'xtype' => 'textfield', 23 | 'value' => '{"keys":{"id":"12345","secret":"12345"},"scope":"email,public_profile"}', 24 | 'area' => 'ha.keys', 25 | ), 26 | 'keys.Vkontakte' => array( 27 | 'xtype' => 'textfield', 28 | 'value' => '{"keys":{"id":"12345","secret":"12345"},"scope":"email"}', 29 | 'area' => 'ha.keys', 30 | ), 31 | 'register_users' => array( 32 | 'xtype' => 'combo-boolean', 33 | 'value' => true, 34 | 'area' => 'ha.main', 35 | ), 36 | 'frontend_css' => array( 37 | 'xtype' => 'textfield', 38 | 'value' => '[[+assetsUrl]]css/web/default.css', 39 | 'area' => 'ha.main', 40 | ), 41 | 42 | ); 43 | 44 | foreach ($tmp as $k => $v) { 45 | /** @var modSystemSetting $setting */ 46 | /** @var modX $modx */ 47 | $setting = $modx->newObject('modSystemSetting'); 48 | $setting->fromArray(array_merge( 49 | array( 50 | 'key' => 'ha.' . $k, 51 | 'namespace' => PKG_NAME_LOWER, 52 | ), 53 | $v 54 | ), '', true, true); 55 | 56 | $settings[] = $setting; 57 | } 58 | 59 | unset($tmp); 60 | return $settings; 61 | -------------------------------------------------------------------------------- /_build/data/transport.snippets.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'file' => 'hybridauth', 8 | 'description' => 'Social authorization', 9 | ), 10 | 'haProfile' => array( 11 | 'file' => 'haprofile', 12 | 'description' => 'Update your profile', 13 | ), 14 | ); 15 | 16 | foreach ($tmp as $k => $v) { 17 | /** @var modSnippet $snippet */ 18 | /** @var modX $modx */ 19 | /** @var array $sources */ 20 | $snippet = $modx->newObject('modSnippet'); 21 | $snippet->fromArray(array( 22 | 'id' => 0, 23 | 'name' => $k, 24 | 'description' => @$v['description'], 25 | 'snippet' => getSnippetContent($sources['source_core'] . '/elements/snippets/snippet.' . $v['file'] . '.php'), 26 | 'static' => BUILD_SNIPPET_STATIC, 27 | 'source' => 1, 28 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/snippet.' . $v['file'] . '.php', 29 | ), '', true, true); 30 | 31 | $properties = include $sources['build'] . 'properties/properties.' . $v['file'] . '.php'; 32 | $snippet->setProperties($properties); 33 | 34 | $snippets[] = $snippet; 35 | } 36 | 37 | unset($tmp, $properties); 38 | return $snippets; 39 | -------------------------------------------------------------------------------- /_build/includes/functions.php: -------------------------------------------------------------------------------- 1 | ')); 14 | } 15 | 16 | 17 | /** 18 | * Recursive directory delete 19 | * 20 | * @param $dir 21 | */ 22 | function removeDir($dir) 23 | { 24 | $dir = rtrim($dir, '/'); 25 | if (is_dir($dir)) { 26 | $objects = scandir($dir); 27 | foreach ($objects as $object) { 28 | if ($object != '.' && $object != '..') { 29 | if (is_dir($dir . '/' . $object)) { 30 | removeDir($dir . '/' . $object); 31 | } else { 32 | unlink($dir . '/' . $object); 33 | } 34 | } 35 | } 36 | rmdir($dir); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /_build/properties/properties.haprofile.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'type' => 'textfield', 8 | 'value' => 'tpl.HybridAuth.profile', 9 | ), 10 | 'profileFields' => array( 11 | 'type' => 'textfield', 12 | 'value' => 'username:25,email:50,fullname:50,phone:12,mobilephone:12,dob:10,gender,address,country,city,state,zip,fax,photo,comment,website', 13 | ), 14 | 'requiredFields' => array( 15 | 'type' => 'textfield', 16 | 'value' => 'username,email,fullname', 17 | ), 18 | 'providerTpl' => array( 19 | 'type' => 'textfield', 20 | 'value' => 'tpl.HybridAuth.provider', 21 | ), 22 | 'activeProviderTpl' => array( 23 | 'type' => 'textfield', 24 | 'value' => 'tpl.HybridAuth.provider.active', 25 | ), 26 | ); 27 | 28 | foreach ($tmp as $k => $v) { 29 | $properties[] = array_merge(array( 30 | 'name' => $k, 31 | 'desc' => 'ha.' . $k, 32 | 'lexicon' => PKG_NAME_LOWER . ':properties', 33 | ), $v); 34 | } 35 | 36 | return $properties; 37 | -------------------------------------------------------------------------------- /_build/properties/properties.hybridauth.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'type' => 'textfield', 8 | 'value' => '', 9 | ), 10 | 'rememberme' => array( 11 | 'type' => 'combo-boolean', 12 | 'value' => true, 13 | ), 14 | 'loginTpl' => array( 15 | 'type' => 'textfield', 16 | 'value' => 'tpl.HybridAuth.login', 17 | ), 18 | 'logoutTpl' => array( 19 | 'type' => 'textfield', 20 | 'value' => 'tpl.HybridAuth.logout', 21 | ), 22 | 'providerTpl' => array( 23 | 'type' => 'textfield', 24 | 'value' => 'tpl.HybridAuth.provider', 25 | ), 26 | 'activeProviderTpl' => array( 27 | 'type' => 'textfield', 28 | 'value' => 'tpl.HybridAuth.provider.active', 29 | ), 30 | 'groups' => array( 31 | 'type' => 'textfield', 32 | 'value' => '', 33 | ), 34 | 'loginContext' => array( 35 | 'type' => 'textfield', 36 | 'value' => '', 37 | ), 38 | 'addContexts' => array( 39 | 'type' => 'textfield', 40 | 'value' => '', 41 | ), 42 | 'loginResourceId' => array( 43 | 'type' => 'numberfield', 44 | 'value' => 0, 45 | ), 46 | 'logoutResourceId' => array( 47 | 'type' => 'numberfield', 48 | 'value' => 0, 49 | ), 50 | 'redirectUri' => array( 51 | 'type' => 'textfield', 52 | 'value' => '', 53 | ), 54 | ); 55 | 56 | foreach ($tmp as $k => $v) { 57 | $properties[] = array_merge(array( 58 | 'name' => $k, 59 | 'desc' => 'ha.' . $k, 60 | 'lexicon' => PKG_NAME_LOWER . ':properties', 61 | ), $v); 62 | } 63 | 64 | return $properties; 65 | -------------------------------------------------------------------------------- /_build/resolvers/resolve.tables.php: -------------------------------------------------------------------------------- 1 | xpdo) { 4 | /** @var modX $modx */ 5 | /** @var array $options */ 6 | $modx = $object->xpdo; 7 | 8 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 9 | case xPDOTransport::ACTION_INSTALL: 10 | case xPDOTransport::ACTION_UPGRADE: 11 | $modelPath = MODX_CORE_PATH . 'components/hybridauth/model/'; 12 | $modx->addPackage('hybridauth', $modelPath); 13 | 14 | $manager = $modx->getManager(); 15 | $manager->createObjectContainer('haUserService'); 16 | $modx->addExtensionPackage('hybridauth', '[[++core_path]]components/hybridauth/model/'); 17 | 18 | $modx->exec( 19 | "UPDATE {$modx->getTableName('modUser')} SET `class_key` = 'modUser' WHERE `class_key` = 'haUser';" 20 | ); 21 | break; 22 | 23 | case xPDOTransport::ACTION_UNINSTALL: 24 | break; 25 | } 26 | } 27 | return true; 28 | -------------------------------------------------------------------------------- /assets/components/hybridauth/connector.php: -------------------------------------------------------------------------------- 1 | getOption('hybridauth.core_path', null, $modx->getOption('core_path') . 'components/hybridauth/'); 9 | require_once $corePath . 'model/hybridauth/hybridauth.class.php'; 10 | $HybridAuth = new HybridAuth($modx); 11 | 12 | /** @var modConnectorRequest $request */ 13 | $request = $modx->request; 14 | $request->handleRequest(array( 15 | 'processors_path' => $HybridAuth->config['processorsPath'], 16 | 'location' => '', 17 | )); 18 | -------------------------------------------------------------------------------- /assets/components/hybridauth/css/mgr/bootstrap.buttons.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.5 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | .btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%} -------------------------------------------------------------------------------- /assets/components/hybridauth/css/mgr/main.css: -------------------------------------------------------------------------------- 1 | /* Grid */ 2 | .x-grid3-col-actions { padding: 3px 0 3px 5px; } 3 | .x-grid3-col-avatar { padding: 2px 0; } 4 | .x-grid3-col-avatar img { height: 36px; display: block; margin: auto; } 5 | /* Actions */ 6 | .action-red { color: darkred !important; } 7 | .action-green { color: darkgreen !important; } 8 | .action-blue { color: cadetblue !important; } 9 | .action-yellow { color: goldenrod !important; } 10 | .action-gray { color: dimgray !important; } 11 | ul.ha-row-actions { margin: 0; padding: 0; list-style: none; } 12 | ul.ha-row-actions li { float: left; } 13 | ul.ha-row-actions .btn { padding: 5px; margin-right: 2px; min-width: 26px; font-size: inherit; } 14 | /* Action menu */ 15 | a.x-menu-item .x-menu-item-text, a.x-menu-item .x-menu-item-text .icon { cursor: pointer; } 16 | a.x-menu-item .x-menu-item-text .icon { line-height: 16px; top: auto; } 17 | .x-menu-list .icon { min-width: 1em; text-align: center; } 18 | .x-menu-list-item:hover .icon { color: inherit !important; } 19 | ul.ha-row-actions .actions-menu { width: 40px; } 20 | ul.ha-row-actions .actions-menu:after { content: " \f107"; } -------------------------------------------------------------------------------- /assets/components/hybridauth/css/web/default.css: -------------------------------------------------------------------------------- 1 | .hybridauth .ha-avatar { 2 | position: absolute; 3 | width: 75px; 4 | margin-top: 15px; 5 | } 6 | 7 | .hybridauth .ha-info { 8 | margin-left: 90px; 9 | display: inline-block; 10 | } 11 | 12 | .ha-icon, 13 | .ha-icon-active { 14 | display: inline-block; 15 | width: 48px; 16 | height: 48px; 17 | margin: 0 2px; 18 | background-image: url('../../img/web/color-icons.png'); 19 | background-repeat: no-repeat; 20 | text-indent: -9999px; 21 | opacity: 1; 22 | } 23 | 24 | .ha-icon:hover { opacity: .8; } 25 | 26 | .ha-icon.active { 27 | background-image: url('../../img/web/grayscale-icons.png'); 28 | opacity: .5 !important; 29 | } 30 | 31 | .ha-icon.facebook { background-position: 0 0; } 32 | 33 | .ha-icon.github { background-position: -48px 0; } 34 | 35 | .ha-icon.google { background-position: -96px 0; } 36 | 37 | .ha-icon.instagram { background-position: -144px 0; } 38 | 39 | .ha-icon.linkedin { background-position: -192px 0; } 40 | 41 | .ha-icon.livejournal { background-position: -240px 0; } 42 | 43 | .ha-icon.mailru { background-position: -288px 0; } 44 | 45 | .ha-icon.odnoklassniki { background-position: -336px 0; } 46 | 47 | .ha-icon.thumblr { background-position: -384px 0; } 48 | 49 | .ha-icon.twitter { background-position: -432px 0; } 50 | 51 | .ha-icon.vimeo { background-position: -480px 0; } 52 | 53 | .ha-icon.vkontakte { background-position: -528px 0; } 54 | 55 | .ha-icon.yandex { background-position: -576px 0; } 56 | 57 | .ha-icon.youtube { background-position: -624px 0; } 58 | 59 | .ha-icon.foursquare { background-position: -672px 0; } 60 | 61 | .ha-icon.modxpro { background-position: -720px 0; } -------------------------------------------------------------------------------- /assets/components/hybridauth/img/web/color-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modx-pro/modx-hybridauth/574abb71323173237ed436b4e51d43316abb587b/assets/components/hybridauth/img/web/color-icons.png -------------------------------------------------------------------------------- /assets/components/hybridauth/img/web/grayscale-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modx-pro/modx-hybridauth/574abb71323173237ed436b4e51d43316abb587b/assets/components/hybridauth/img/web/grayscale-icons.png -------------------------------------------------------------------------------- /assets/components/hybridauth/js/mgr/hybridauth.js: -------------------------------------------------------------------------------- 1 | var HybridAuth = function (config) { 2 | config = config || {}; 3 | HybridAuth.superclass.constructor.call(this, config); 4 | }; 5 | 6 | Ext.extend(HybridAuth, Ext.Component, { 7 | grid: {}, 8 | combo: {}, 9 | window: {}, 10 | config: {}, 11 | utils: {} 12 | }); 13 | Ext.reg('HybridAuth', HybridAuth); 14 | 15 | HybridAuth = new HybridAuth(); 16 | 17 | Ext.ComponentMgr.onAvailable("modx-user-tabs", function() { 18 | this.on("beforerender", function() { 19 | this.add({ 20 | title: _("ha.services"), 21 | border: false, 22 | items: [{ 23 | layout: "anchor", 24 | border: false, 25 | items: [{ 26 | html: _("ha.services_tip"), 27 | border: false, 28 | bodyCssClass: "panel-desc" 29 | }, { 30 | xtype: "hybridauth-grid-services", 31 | anchor: "100%", 32 | cls: "main-wrapper", 33 | userId: HybridAuth.config.user_id 34 | }] 35 | }] 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /assets/components/hybridauth/js/mgr/misc/utils.js: -------------------------------------------------------------------------------- 1 | HybridAuth.utils.getMenu = function (actions, grid, selected) { 2 | var menu = []; 3 | var cls, icon, title, action; 4 | 5 | var has_delete = false; 6 | for (var i in actions) { 7 | if (!actions.hasOwnProperty(i)) { 8 | continue; 9 | } 10 | 11 | var a = actions[i]; 12 | if (!a['menu']) { 13 | if (a == '-') { 14 | menu.push('-'); 15 | } 16 | continue; 17 | } 18 | else if (menu.length > 0 && !has_delete && (/^remove/i.test(a['action']) || /^delete/i.test(a['action']))) { 19 | menu.push('-'); 20 | has_delete = true; 21 | } 22 | 23 | if (selected.length > 1) { 24 | if (!a['multiple']) { 25 | continue; 26 | } 27 | else if (typeof(a['multiple']) == 'string') { 28 | a['title'] = a['multiple']; 29 | } 30 | } 31 | 32 | icon = a['icon'] ? a['icon'] : ''; 33 | if (typeof(a['cls']) == 'object') { 34 | if (typeof(a['cls']['menu']) != 'undefined') { 35 | icon += ' ' + a['cls']['menu']; 36 | } 37 | } 38 | else { 39 | cls = a['cls'] ? a['cls'] : ''; 40 | } 41 | title = a['title'] ? a['title'] : a['title']; 42 | action = a['action'] ? grid[a['action']] : ''; 43 | 44 | menu.push({ 45 | handler: action, 46 | text: String.format( 47 | '{2}', 48 | cls, icon, title 49 | ), 50 | scope: grid 51 | }); 52 | } 53 | 54 | return menu; 55 | }; 56 | 57 | HybridAuth.utils.renderActions = function (value, props, row) { 58 | var res = []; 59 | var cls, icon, title, action, item; 60 | for (var i in row.data.actions) { 61 | if (!row.data.actions.hasOwnProperty(i)) { 62 | continue; 63 | } 64 | var a = row.data.actions[i]; 65 | if (!a['button']) { 66 | continue; 67 | } 68 | 69 | icon = a['icon'] ? a['icon'] : ''; 70 | if (typeof(a['cls']) == 'object') { 71 | if (typeof(a['cls']['button']) != 'undefined') { 72 | icon += ' ' + a['cls']['button']; 73 | } 74 | } 75 | else { 76 | cls = a['cls'] ? a['cls'] : ''; 77 | } 78 | action = a['action'] ? a['action'] : ''; 79 | title = a['title'] ? a['title'] : ''; 80 | 81 | item = String.format( 82 | '
  • ', 83 | cls, icon, action, title 84 | ); 85 | 86 | res.push(item); 87 | } 88 | 89 | return String.format( 90 | '', 91 | res.join('') 92 | ); 93 | }; -------------------------------------------------------------------------------- /assets/components/hybridauth/js/mgr/widgets/service.grid.js: -------------------------------------------------------------------------------- 1 | HybridAuth.grid.Services = function (config) { 2 | config = config || {}; 3 | var baseParams = { 4 | action: 'mgr/service/getlist' 5 | }; 6 | if (config.userId) { 7 | baseParams.user_id = config.userId; 8 | } 9 | Ext.applyIf(config, { 10 | url: HybridAuth.config.connectorUrl, 11 | id: 'ha-row', 12 | baseParams: baseParams, 13 | remoteSort: true, 14 | paging: true, 15 | preventRender: true, 16 | sm: new Ext.grid.CheckboxSelectionModel(), 17 | fields: this.getFields(config), 18 | columns: this.getColumns(config) 19 | }); 20 | HybridAuth.grid.Services.superclass.constructor.call(this, config); 21 | }; 22 | Ext.extend(HybridAuth.grid.Services, MODx.grid.Grid, { 23 | 24 | getMenu: function (grid, rowIndex) { 25 | var ids = this._getSelectedIds(); 26 | 27 | var row = grid.getStore().getAt(rowIndex); 28 | var menu = HybridAuth.utils.getMenu(row.data['actions'], this, ids); 29 | 30 | this.addContextMenuItem(menu); 31 | }, 32 | 33 | getFields: function () { 34 | return [ 35 | 'id', 36 | 'hash', 37 | 'createdon', 38 | 'provider', 39 | 'identifier', 40 | 'profileurl', 41 | 'photourl', 42 | 'displayname', 43 | 'email', 44 | 'actions' 45 | ] 46 | }, 47 | 48 | getColumns: function () { 49 | return [{ 50 | header: '', 51 | dataIndex: 'hash', 52 | sortable: false, 53 | width: 45, 54 | renderer: this._renderAvatar, 55 | id: 'avatar' 56 | }, { 57 | header: _('ha.service_createdon'), 58 | dataIndex: 'createdon', 59 | sortable: true 60 | }, { 61 | header: _('ha.service_provider'), 62 | dataIndex: 'provider', 63 | sortable: true 64 | }, { 65 | header: _('ha.service_identifier'), 66 | dataIndex: 'identifier', 67 | sortable: true, 68 | renderer: this._renderProfileUrl 69 | }, { 70 | header: _('ha.service_displayname'), 71 | dataIndex: 'displayname', 72 | sortable: true 73 | }, { 74 | header: _('ha.service_email'), 75 | dataIndex: 'email', 76 | sortable: true, 77 | renderer: this._renderEmail 78 | }, { 79 | header: '', 80 | dataIndex: 'actions', 81 | renderer: HybridAuth.utils.renderActions, 82 | sortable: false, 83 | width: 35, 84 | id: 'actions' 85 | }]; 86 | }, 87 | 88 | removeItem: function () { 89 | var ids = this._getSelectedIds(); 90 | if (!ids.length) { 91 | return false; 92 | } 93 | MODx.msg.confirm({ 94 | title: ids.length > 1 95 | ? _('ha.services_remove') 96 | : _('ha.service_remove'), 97 | text: ids.length > 1 98 | ? _('ha.services_remove_confirm') 99 | : _('ha.service_remove_confirm'), 100 | url: this.config.url, 101 | params: { 102 | action: 'mgr/service/remove', 103 | ids: Ext.util.JSON.encode(ids), 104 | }, 105 | listeners: { 106 | success: { 107 | fn: function () { 108 | this.refresh(); 109 | }, scope: this 110 | } 111 | } 112 | }); 113 | return true; 114 | }, 115 | 116 | onClick: function (e) { 117 | var elem = e.getTarget(); 118 | if (elem.nodeName == 'BUTTON') { 119 | var row = this.getSelectionModel().getSelected(); 120 | if (typeof(row) != 'undefined') { 121 | var action = elem.getAttribute('action'); 122 | if (action == 'showMenu') { 123 | var ri = this.getStore().find('id', row.id); 124 | return this._showMenu(this, ri, e); 125 | } 126 | else if (typeof this[action] === 'function') { 127 | this.menu.record = row.data; 128 | return this[action](this, e); 129 | } 130 | } 131 | } 132 | return this.processEvent('click', e); 133 | }, 134 | 135 | _getSelectedIds: function () { 136 | var ids = []; 137 | var selected = this.getSelectionModel().getSelections(); 138 | 139 | for (var i in selected) { 140 | if (!selected.hasOwnProperty(i)) { 141 | continue; 142 | } 143 | ids.push(selected[i]['id']); 144 | } 145 | 146 | return ids; 147 | }, 148 | 149 | _renderAvatar: function (v, md, record) { 150 | return ''; 152 | }, 153 | 154 | _renderProfileUrl: function (v, md, record) { 155 | var url = record.get('profileurl'); 156 | if (typeof(url) == 'string') { 157 | url = url.trim(); 158 | if (url != '') { 159 | return '' + v + ''; 160 | } 161 | } 162 | 163 | return v; 164 | }, 165 | 166 | _renderEmail: function (v) { 167 | return '' + v + ''; 168 | } 169 | }); 170 | Ext.reg('hybridauth-grid-services', HybridAuth.grid.Services); 171 | -------------------------------------------------------------------------------- /core/components/hybridauth/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bezumkin/modx-hybridauth", 3 | "require": { 4 | "hybridauth/hybridauth": "3.7.*" 5 | }, 6 | "autoload": { 7 | "classmap": [ 8 | "providers/" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /core/components/hybridauth/docs/changelog.txt: -------------------------------------------------------------------------------- 1 | Changelog for HybridAuth. 2 | 3 | 3.1.1-pl 4 | ============== 5 | - #50 Fix position of lexicon in manager 6 | - #53 fix used modx tags in provider urls 7 | 8 | 3.1.0-pl 9 | ============== 10 | - Refactoring PHP to PSR-12 11 | - Updated HybridAuth core to 3.7.1 12 | 13 | 3.0.2-pl 14 | ============== 15 | - Fixed retrieving date of birth from remote profile. 16 | 17 | 3.0.1-pl 18 | ============== 19 | - Updated HybridAuth core to 3.0.0 stable 20 | - Fixed php type of "country" in model map. 21 | 22 | 3.0.0-pl 23 | ============== 24 | - Updated HybridAuth core. 25 | 26 | 3.0.0-rc 27 | ============== 28 | - Refactored to use HybridAuth 3. 29 | - Updated default providers. 30 | 31 | 2.1.0 pl 32 | ============== 33 | - Added modx.pro provider. 34 | - Improved compatibility with PHP 7.2. 35 | - Improved ExtJs grid in manager. 36 | 37 | 2.0.4 pl 38 | ============== 39 | - Fixed possible "No provider ID specified" message in the system log. 40 | - Updated HybridAuth library to version 2.9.1. 41 | 42 | 2.0.3 pl 43 | ============== 44 | - Improved the handling of exceptions. 45 | - Fixed debug mode. 46 | 47 | 2.0.2 pl 48 | ============== 49 | - Fixed possible XSS in the authorization links. 50 | 51 | 2.0.1 pl 52 | ============== 53 | - Removed error "You cannot access this page directly" from system log. 54 | 55 | 2.0.0 pl 56 | ============== 57 | - PSR-2 58 | - Updated HybridAuth library to version 2.8.2. 59 | - HybridAuth library integrated via composer. 60 | - Ability to unbind services from a profile of user. 61 | - If pdoTools is installed, the component will use it for the processing of a chunks. 62 | 63 | 1.1.4 pl 64 | ============== 65 | - [#34] Fixed scopes in Facebook provider. 66 | - Fixed possible E_WARNING in Vkontakte provider. 67 | 68 | 1.1.3 pl 69 | ============== 70 | - [#37] Increased length of some haUserService fields. 71 | 72 | 1.1.2 pl 73 | ============== 74 | - Updated main oAuth providers, including Google and Facebook. 75 | 76 | 1.1.1 pl 77 | ============== 78 | - [#17] Fixed work with enabled php-apc after updated HybridAuth core to version 2.3.0. 79 | 80 | 1.1.0 pl 81 | ============== 82 | - Updated HybridAuth core to version 2.3.0. 83 | - Shows more errors from HybridAuth in MODX log. 84 | 85 | 1.0.0 pl 86 | ============== 87 | - Removed object haUser. All existing users will be converted to modUser on package upgrade. 88 | - Removed function filter_var() for email validation. 89 | - Returned back transparent images. 90 | 91 | 0.9.0 pl 92 | ============== 93 | - Added possibility to view user's linked services in manager. 94 | 95 | 0.8.8 pl1 96 | ============== 97 | - [#26] Fixed calculation of time of the queries. 98 | - Fixed E_NOTICE on line 99 of hybridauth.class.php. 99 | 100 | 0.8.7 pl 101 | ============== 102 | - [#23] Fixed parameter "debug" for HybridAuth. 103 | - [#21] Improved usernames. 104 | 105 | 0.8.6 pl 106 | ============== 107 | - [#20] Improved work with context settings. 108 | - Fixed method makePlaceholders. 109 | 110 | 0.8.5 pl4 111 | ============== 112 | - Improved package uninstall and reinstall. 113 | - [#17] Fixed work with enabled php-apc. 114 | - Added Foursquare icon. 115 | - Fixed possible E_WARNING on initialization. 116 | 117 | 0.8.4 pl 118 | ============== 119 | - Added rel="nofollow" into chunk with link to provider. 120 | - Improved description of system settings. 121 | 122 | 0.8.3 pl 123 | ============== 124 | - Improved generation of providers links. 125 | 126 | 0.8.2 pl 127 | ============== 128 | - Added parameter "&redirectUri=``" for solve issue "redirect_uri_mismatch" when using multiple contexts. 129 | - Context settings now can override providers keys in system settings. Very helpful for multiple contexts. 130 | 131 | 0.8.1 pl 132 | ============== 133 | - Fixed bug with saving parameters to $_SESSION. 134 | 135 | 0.8.0 pl 136 | ============== 137 | - [#7] Fixed generation of links for sites in subfolder. 138 | - [#4] Fixed login to separate contexts. 139 | - Improved support of multiple contexts. 140 | 141 | 0.7.0 pl2 142 | ============== 143 | - New snippet "haProfile" for update user profile. 144 | - Automatic generation of links of providers. 145 | - Improved chunks, added icons for some providers. 146 | - Automatic logout of users that was been blocked by administrator. 147 | - Added virtual field "gravatar" to class "haUser". You can get it with $modx->user->get('gravatar');. 148 | - Extension package is removed from system settings when you uninstall component. 149 | - Replaced file "action.php" to plugin "HybridAuth". 150 | - Added new providers: "Draugiem" and "Xing". 151 | - [#3] Fixed "No foreign key definition for parentClass: modUser using relation alias: Services" log entries. 152 | - Fixed order of links to providers, specified in the parameter "&providers". 153 | 154 | 0.6.0 pl 155 | ============== 156 | - Added ability to disable new user registrations. See system setting "ha.register_users". 157 | 158 | 0.5.0 beta 159 | ============== 160 | - Fixed login trough vk.com 161 | - Updated HybridAuth core to version 2.1.2 162 | 163 | 0.4.0 beta 164 | ============== 165 | - Updated HybridAuth core to version 2.1.1 166 | - Improved initialization of main class 167 | 168 | 0.3.3 beta 169 | ============== 170 | - Fixed issue with empty email 171 | 172 | 0.3.2 beta 173 | ============== 174 | - Added exception handler for catching all exceptions from HybridAuth into MODX system log 175 | 176 | 0.3.1 beta 177 | ============== 178 | - Changing user class to haUser on login through remote service. 179 | - On uninstall of component all haUsers becomes modUsers. 180 | 181 | 0.3.0 beta 182 | ============== 183 | - Fixed save of a photo in profile. 184 | - Improved errors handling. 185 | - Fixed increment of username if remote username exists on site. 186 | - If authenticated user linking remote service record, that already exists in remote profiles of the site - this record changes the owner. You can re-link any of your records to any accounts on site. 187 | 188 | 0.2.0 beta 189 | ============== 190 | - Added parameter &groups=``. For example, &groups=`Users:1` will add new user to group "Users" with role "member" 191 | - Updated snippet params, added russian localization. 192 | - Chunks localization 193 | - Updated readme 194 | 195 | 0.1.0 beta 196 | ============== 197 | - Initial release. -------------------------------------------------------------------------------- /core/components/hybridauth/docs/license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | -------------------------- 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 6 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies 9 | of this license document, but changing it is not allowed. 10 | 11 | Preamble 12 | -------- 13 | 14 | The licenses for most software are designed to take away your 15 | freedom to share and change it. By contrast, the GNU General Public 16 | License is intended to guarantee your freedom to share and change free 17 | software--to make sure the software is free for all its users. This 18 | General Public License applies to most of the Free Software 19 | Foundation's software and to any other program whose authors commit to 20 | using it. (Some other Free Software Foundation software is covered by 21 | the GNU Library General Public License instead.) You can apply it to 22 | your programs, too. 23 | 24 | When we speak of free software, we are referring to freedom, not 25 | price. Our General Public Licenses are designed to make sure that you 26 | have the freedom to distribute copies of free software (and charge for 27 | this service if you wish), that you receive source code or can get it 28 | if you want it, that you can change the software or use pieces of it 29 | in new free programs; and that you know you can do these things. 30 | 31 | To protect your rights, we need to make restrictions that forbid 32 | anyone to deny you these rights or to ask you to surrender the rights. 33 | These restrictions translate to certain responsibilities for you if you 34 | distribute copies of the software, or if you modify it. 35 | 36 | For example, if you distribute copies of such a program, whether 37 | gratis or for a fee, you must give the recipients all the rights that 38 | you have. You must make sure that they, too, receive or can get the 39 | source code. And you must show them these terms so they know their 40 | rights. 41 | 42 | We protect your rights with two steps: (1) copyright the software, and 43 | (2) offer you this license which gives you legal permission to copy, 44 | distribute and/or modify the software. 45 | 46 | Also, for each author's protection and ours, we want to make certain 47 | that everyone understands that there is no warranty for this free 48 | software. If the software is modified by someone else and passed on, we 49 | want its recipients to know that what they have is not the original, so 50 | that any problems introduced by others will not reflect on the original 51 | authors' reputations. 52 | 53 | Finally, any free program is threatened constantly by software 54 | patents. We wish to avoid the danger that redistributors of a free 55 | program will individually obtain patent licenses, in effect making the 56 | program proprietary. To prevent this, we have made it clear that any 57 | patent must be licensed for everyone's free use or not licensed at all. 58 | 59 | The precise terms and conditions for copying, distribution and 60 | modification follow. 61 | 62 | 63 | GNU GENERAL PUBLIC LICENSE 64 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 65 | --------------------------------------------------------------- 66 | 67 | 0. This License applies to any program or other work which contains 68 | a notice placed by the copyright holder saying it may be distributed 69 | under the terms of this General Public License. The "Program", below, 70 | refers to any such program or work, and a "work based on the Program" 71 | means either the Program or any derivative work under copyright law: 72 | that is to say, a work containing the Program or a portion of it, 73 | either verbatim or with modifications and/or translated into another 74 | language. (Hereinafter, translation is included without limitation in 75 | the term "modification".) Each licensee is addressed as "you". 76 | 77 | Activities other than copying, distribution and modification are not 78 | covered by this License; they are outside its scope. The act of 79 | running the Program is not restricted, and the output from the Program 80 | is covered only if its contents constitute a work based on the 81 | Program (independent of having been made by running the Program). 82 | Whether that is true depends on what the Program does. 83 | 84 | 1. You may copy and distribute verbatim copies of the Program's 85 | source code as you receive it, in any medium, provided that you 86 | conspicuously and appropriately publish on each copy an appropriate 87 | copyright notice and disclaimer of warranty; keep intact all the 88 | notices that refer to this License and to the absence of any warranty; 89 | and give any other recipients of the Program a copy of this License 90 | along with the Program. 91 | 92 | You may charge a fee for the physical act of transferring a copy, and 93 | you may at your option offer warranty protection in exchange for a fee. 94 | 95 | 2. You may modify your copy or copies of the Program or any portion 96 | of it, thus forming a work based on the Program, and copy and 97 | distribute such modifications or work under the terms of Section 1 98 | above, provided that you also meet all of these conditions: 99 | 100 | a) You must cause the modified files to carry prominent notices 101 | stating that you changed the files and the date of any change. 102 | 103 | b) You must cause any work that you distribute or publish, that in 104 | whole or in part contains or is derived from the Program or any 105 | part thereof, to be licensed as a whole at no charge to all third 106 | parties under the terms of this License. 107 | 108 | c) If the modified program normally reads commands interactively 109 | when run, you must cause it, when started running for such 110 | interactive use in the most ordinary way, to print or display an 111 | announcement including an appropriate copyright notice and a 112 | notice that there is no warranty (or else, saying that you provide 113 | a warranty) and that users may redistribute the program under 114 | these conditions, and telling the user how to view a copy of this 115 | License. (Exception: if the Program itself is interactive but 116 | does not normally print such an announcement, your work based on 117 | the Program is not required to print an announcement.) 118 | 119 | These requirements apply to the modified work as a whole. If 120 | identifiable sections of that work are not derived from the Program, 121 | and can be reasonably considered independent and separate works in 122 | themselves, then this License, and its terms, do not apply to those 123 | sections when you distribute them as separate works. But when you 124 | distribute the same sections as part of a whole which is a work based 125 | on the Program, the distribution of the whole must be on the terms of 126 | this License, whose permissions for other licensees extend to the 127 | entire whole, and thus to each and every part regardless of who wrote it. 128 | 129 | Thus, it is not the intent of this section to claim rights or contest 130 | your rights to work written entirely by you; rather, the intent is to 131 | exercise the right to control the distribution of derivative or 132 | collective works based on the Program. 133 | 134 | In addition, mere aggregation of another work not based on the Program 135 | with the Program (or with a work based on the Program) on a volume of 136 | a storage or distribution medium does not bring the other work under 137 | the scope of this License. 138 | 139 | 3. You may copy and distribute the Program (or a work based on it, 140 | under Section 2) in object code or executable form under the terms of 141 | Sections 1 and 2 above provided that you also do one of the following: 142 | 143 | a) Accompany it with the complete corresponding machine-readable 144 | source code, which must be distributed under the terms of Sections 145 | 1 and 2 above on a medium customarily used for software interchange; or, 146 | 147 | b) Accompany it with a written offer, valid for at least three 148 | years, to give any third party, for a charge no more than your 149 | cost of physically performing source distribution, a complete 150 | machine-readable copy of the corresponding source code, to be 151 | distributed under the terms of Sections 1 and 2 above on a medium 152 | customarily used for software interchange; or, 153 | 154 | c) Accompany it with the information you received as to the offer 155 | to distribute corresponding source code. (This alternative is 156 | allowed only for noncommercial distribution and only if you 157 | received the program in object code or executable form with such 158 | an offer, in accord with Subsection b above.) 159 | 160 | The source code for a work means the preferred form of the work for 161 | making modifications to it. For an executable work, complete source 162 | code means all the source code for all modules it contains, plus any 163 | associated interface definition files, plus the scripts used to 164 | control compilation and installation of the executable. However, as a 165 | special exception, the source code distributed need not include 166 | anything that is normally distributed (in either source or binary 167 | form) with the major components (compiler, kernel, and so on) of the 168 | operating system on which the executable runs, unless that component 169 | itself accompanies the executable. 170 | 171 | If distribution of executable or object code is made by offering 172 | access to copy from a designated place, then offering equivalent 173 | access to copy the source code from the same place counts as 174 | distribution of the source code, even though third parties are not 175 | compelled to copy the source along with the object code. 176 | 177 | 4. You may not copy, modify, sublicense, or distribute the Program 178 | except as expressly provided under this License. Any attempt 179 | otherwise to copy, modify, sublicense or distribute the Program is 180 | void, and will automatically terminate your rights under this License. 181 | However, parties who have received copies, or rights, from you under 182 | this License will not have their licenses terminated so long as such 183 | parties remain in full compliance. 184 | 185 | 5. You are not required to accept this License, since you have not 186 | signed it. However, nothing else grants you permission to modify or 187 | distribute the Program or its derivative works. These actions are 188 | prohibited by law if you do not accept this License. Therefore, by 189 | modifying or distributing the Program (or any work based on the 190 | Program), you indicate your acceptance of this License to do so, and 191 | all its terms and conditions for copying, distributing or modifying 192 | the Program or works based on it. 193 | 194 | 6. Each time you redistribute the Program (or any work based on the 195 | Program), the recipient automatically receives a license from the 196 | original licensor to copy, distribute or modify the Program subject to 197 | these terms and conditions. You may not impose any further 198 | restrictions on the recipients' exercise of the rights granted herein. 199 | You are not responsible for enforcing compliance by third parties to 200 | this License. 201 | 202 | 7. If, as a consequence of a court judgment or allegation of patent 203 | infringement or for any other reason (not limited to patent issues), 204 | conditions are imposed on you (whether by court order, agreement or 205 | otherwise) that contradict the conditions of this License, they do not 206 | excuse you from the conditions of this License. If you cannot 207 | distribute so as to satisfy simultaneously your obligations under this 208 | License and any other pertinent obligations, then as a consequence you 209 | may not distribute the Program at all. For example, if a patent 210 | license would not permit royalty-free redistribution of the Program by 211 | all those who receive copies directly or indirectly through you, then 212 | the only way you could satisfy both it and this License would be to 213 | refrain entirely from distribution of the Program. 214 | 215 | If any portion of this section is held invalid or unenforceable under 216 | any particular circumstance, the balance of the section is intended to 217 | apply and the section as a whole is intended to apply in other 218 | circumstances. 219 | 220 | It is not the purpose of this section to induce you to infringe any 221 | patents or other property right claims or to contest validity of any 222 | such claims; this section has the sole purpose of protecting the 223 | integrity of the free software distribution system, which is 224 | implemented by public license practices. Many people have made 225 | generous contributions to the wide range of software distributed 226 | through that system in reliance on consistent application of that 227 | system; it is up to the author/donor to decide if he or she is willing 228 | to distribute software through any other system and a licensee cannot 229 | impose that choice. 230 | 231 | This section is intended to make thoroughly clear what is believed to 232 | be a consequence of the rest of this License. 233 | 234 | 8. If the distribution and/or use of the Program is restricted in 235 | certain countries either by patents or by copyrighted interfaces, the 236 | original copyright holder who places the Program under this License 237 | may add an explicit geographical distribution limitation excluding 238 | those countries, so that distribution is permitted only in or among 239 | countries not thus excluded. In such case, this License incorporates 240 | the limitation as if written in the body of this License. 241 | 242 | 9. The Free Software Foundation may publish revised and/or new versions 243 | of the General Public License from time to time. Such new versions will 244 | be similar in spirit to the present version, but may differ in detail to 245 | address new problems or concerns. 246 | 247 | Each version is given a distinguishing version number. If the Program 248 | specifies a version number of this License which applies to it and "any 249 | later version", you have the option of following the terms and conditions 250 | either of that version or of any later version published by the Free 251 | Software Foundation. If the Program does not specify a version number of 252 | this License, you may choose any version ever published by the Free Software 253 | Foundation. 254 | 255 | 10. If you wish to incorporate parts of the Program into other free 256 | programs whose distribution conditions are different, write to the author 257 | to ask for permission. For software which is copyrighted by the Free 258 | Software Foundation, write to the Free Software Foundation; we sometimes 259 | make exceptions for this. Our decision will be guided by the two goals 260 | of preserving the free status of all derivatives of our free software and 261 | of promoting the sharing and reuse of software generally. 262 | 263 | NO WARRANTY 264 | ----------- 265 | 266 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 267 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 268 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 269 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 270 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 271 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 272 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 273 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 274 | REPAIR OR CORRECTION. 275 | 276 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 277 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 278 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 279 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 280 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 281 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 282 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 283 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 284 | POSSIBILITY OF SUCH DAMAGES. 285 | 286 | --------------------------- 287 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /core/components/hybridauth/docs/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------- 2 | HybridAuth 3 | -------------------- 4 | Author: Vasiliy Naumkin 5 | -------------------- 6 | An integration of open source social sign on php library - http://hybridauth.sourceforge.net/ into MODX Revolution. 7 | 8 | The main goal of HybridAuth library is to act as an abstract api between your application and various social apis and identities providers such as Facebook, Twitter, MySpace, LinkedIn, Google and Yahoo. 9 | 10 | HybridAuth enable developers to easily build social applications to engage websites vistors and customers on a social level by implementing social signin, social sharing, users profiles, friends list, activities stream, status updates and more. 11 | 12 | Feel free to suggest ideas/improvements/bugs on GitHub: 13 | http://github.com/bezumkin/modx-hybridauth/issues 14 | 15 | -------------------- 16 | Installation 17 | -------------------- 18 | Download and install it with MODX package manager 19 | 20 | Then: 21 | 1. Register and get api keys from needed services. For example, create twitter application - https://dev.twitter.com/apps/new 22 | 2. Open system settings in manager, switch to hybridauth and make\update ha.keys.Servicename. In our wxample it will be ha.keys.Twitter 23 | 3. You need to set your keys as json sting with array. {"key":"you key from twitter","secret":"secret from twitter"}. It needed for proper initialization of the library (http://hybridauth.sourceforge.net/userguide/Configuration.html). 24 | 4. Now you can run snippet [[!HybriAuth?providers=`Twitter`]] on any page. 25 | 26 | If there will be any errors on library initialization - it will be logged in in system log. 27 | 28 | I recorded simple video with Twitter login http://www.youtube.com/watch?v=ron_VTaQeWE for you. -------------------------------------------------------------------------------- /core/components/hybridauth/elements/chunks/chunk.login.tpl: -------------------------------------------------------------------------------- 1 | [[%ha.login_intro]] 2 |
    3 | [[+providers]] 4 | 5 | [[+error:notempty=` 6 |
    [[+error]]
    `]] -------------------------------------------------------------------------------- /core/components/hybridauth/elements/chunks/chunk.logout.tpl: -------------------------------------------------------------------------------- 1 |
    2 | [[+username]] 3 | 4 | 5 | [[%ha.greeting]] [[+username]] ([[+fullname]])! [[%ha.logout]] 6 |

    7 | [[%ha.providers_available]]
    8 | [[+providers]] 9 |
    10 | 11 |
    12 | 13 | [[+error:notempty=` 14 |
    [[+error]]
    `]] 15 | -------------------------------------------------------------------------------- /core/components/hybridauth/elements/chunks/chunk.profile.tpl: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 |
    6 | [[+email]] 7 |
    8 | [[%ha.gravatar_desc]] 9 |
    10 |
    11 | 12 |
    13 | 14 |
    15 | 16 | [[+error.username]] 17 |
    18 |
    19 | 20 |
    21 | 22 |
    23 | 24 | [[+error.fullname]] 25 |
    26 |
    27 | 28 |
    29 | 30 |
    31 | 32 | [[+error.email]] 33 |
    34 |
    35 | 36 |
    37 | 38 |
    39 | [[+providers]] 40 |
    41 |
    42 | 43 | 44 |
    45 | 46 |    47 | [[%ha.logout]] 48 |
    49 |
    50 | [[+success:is=`1`:then=` 51 |
    [[%ha.profile_update_success]]
    `]] 52 | [[+success:is=`0`:then=` 53 |
    [[%ha.profile_update_error]] [[+error.message]]
    `]] -------------------------------------------------------------------------------- /core/components/hybridauth/elements/chunks/chunk.provider.tpl: -------------------------------------------------------------------------------- 1 | [[+title]] 2 | -------------------------------------------------------------------------------- /core/components/hybridauth/elements/chunks/chunk.provider_active.tpl: -------------------------------------------------------------------------------- 1 | [[+title]] 2 | -------------------------------------------------------------------------------- /core/components/hybridauth/elements/plugins/plugin.hybridauth.php: -------------------------------------------------------------------------------- 1 | event->name) { 5 | case 'OnHandleRequest': 6 | if ($modx->context->key != 'web' && !$modx->user->id) { 7 | if ($user = $modx->getAuthenticatedUser($modx->context->key)) { 8 | $modx->user = $user; 9 | $modx->getUser($modx->context->key); 10 | } 11 | } 12 | 13 | if ($modx->user->isAuthenticated($modx->context->key)) { 14 | if (!$modx->user->active || $modx->user->Profile->blocked) { 15 | $modx->runProcessor('security/logout'); 16 | $modx->sendRedirect($modx->makeUrl($modx->getOption('site_start'), '', '', 'full')); 17 | } 18 | } 19 | 20 | if (!empty($_REQUEST['hauth_action']) || !empty($_REQUEST['hauth_done'])) { 21 | $config = !empty($_SESSION['HybridAuth'][$modx->context->key]) 22 | ? $_SESSION['HybridAuth'][$modx->context->key] 23 | : array(); 24 | 25 | $path = MODX_CORE_PATH . 'components/hybridauth/model/hybridauth/'; 26 | /** @var HybridAuth $HybridAuth */ 27 | if ($HybridAuth = $modx->getService('HybridAuth', 'HybridAuth', $path, $config)) { 28 | if (!empty($_REQUEST['hauth_action'])) { 29 | switch ($_REQUEST['hauth_action']) { 30 | case 'login': 31 | if (!empty($_REQUEST['provider'])) { 32 | $HybridAuth->Login($_REQUEST['provider']); 33 | } else { 34 | $HybridAuth->Refresh(); 35 | } 36 | break; 37 | case 'logout': 38 | $HybridAuth->Logout(); 39 | break; 40 | case 'unbind': 41 | if (!empty($_REQUEST['provider'])) { 42 | $HybridAuth->runProcessor('web/service/remove', array( 43 | 'provider' => $_REQUEST['provider'], 44 | )); 45 | } 46 | $HybridAuth->Refresh(); 47 | break; 48 | } 49 | } else { 50 | $HybridAuth->Login($_REQUEST['hauth_done']); 51 | } 52 | } 53 | } 54 | break; 55 | 56 | case 'OnWebAuthentication': 57 | $modx->event->_output = !empty($_SESSION['HybridAuth']['verified']); 58 | unset($_SESSION['HybridAuth']['verified']); 59 | break; 60 | 61 | case 'OnUserFormPrerender': 62 | /** @var modUser $user */ 63 | if (!isset($user) || $user->get('id') < 1) { 64 | return; 65 | } 66 | $path = MODX_CORE_PATH . 'components/hybridauth/model/hybridauth/'; 67 | if ($HybridAuth = $modx->getService('HybridAuth', 'HybridAuth', $path)) { 68 | $HybridAuth->regManagerTab($modx->controller, $user); 69 | } 70 | break; 71 | } 72 | -------------------------------------------------------------------------------- /core/components/hybridauth/elements/snippets/snippet.haprofile.php: -------------------------------------------------------------------------------- 1 | error->reset(); 6 | if (!$modx->loadClass('hybridauth', MODX_CORE_PATH . 'components/hybridauth/model/hybridauth/', false, true)) { 7 | return; 8 | } 9 | $HybridAuth = new HybridAuth($modx, $scriptProperties); 10 | $HybridAuth->initialize($modx->context->key); 11 | 12 | if ($modx->error->hasError()) { 13 | return $modx->error->message; 14 | } elseif (!$modx->user->isAuthenticated($modx->context->key)) { 15 | return $modx->lexicon('ha_err_not_logged_in'); 16 | } 17 | 18 | if (empty($profileTpl)) { 19 | $profileTpl = 'tpl.HybridAuth.profile'; 20 | } 21 | if (empty($profileFields)) { 22 | $profileFields = 'username:25,email:50,fullname:50,phone:12,mobilephone:12,dob:10,gender,address,country,city,state,zip,fax,photo,comment,website'; 23 | } 24 | if (empty($requiredFields)) { 25 | $requiredFields = 'username,email,fullname'; 26 | } 27 | if (empty($providerTpl)) { 28 | $providerTpl = 'tpl.HybridAuth.provider'; 29 | } 30 | if (empty($activeProviderTpl)) { 31 | $activeProviderTpl = 'tpl.HybridAuth.provider.active'; 32 | } 33 | $data = array(); 34 | 35 | // Update of profile 36 | if ((!empty($_REQUEST['action']) && strtolower($_REQUEST['action']) == 'updateprofile') || (!empty($_REQUEST['hauth_action']) && strtolower($_REQUEST['hauth_action']) == 'updateprofile')) { 37 | $profileFields = array_map('trim', explode(',', $profileFields)); 38 | foreach ($profileFields as $field) { 39 | if (strpos($field, ':') !== false) { 40 | list($key, $length) = explode(':', $field); 41 | } else { 42 | $key = $field; 43 | $length = 0; 44 | } 45 | 46 | if (isset($_REQUEST[$key])) { 47 | if ($key == 'comment') { 48 | $data[$key] = empty($length) ? $_REQUEST[$key] : substr($_REQUEST[$key], $length); 49 | } else if ($key == 'extended') { 50 | foreach ($_REQUEST[$key] as $k => $v) { 51 | $data[$key][$k] = $HybridAuth->Sanitize($_REQUEST[$key][$k], $length); 52 | } 53 | } else { 54 | $data[$key] = $HybridAuth->Sanitize($_REQUEST[$key], $length); 55 | } 56 | } 57 | } 58 | 59 | $data['requiredFields'] = array_map('trim', explode(',', $requiredFields)); 60 | 61 | if (isset($data['extended']) && !empty($data['extended'])) { 62 | $profile = $modx->user->getOne('Profile'); 63 | $extended = $profile->get('extended'); 64 | $new_extended = array_merge($extended, $data['extended']); 65 | $data['extended'] = $new_extended; 66 | } 67 | 68 | /** @var modProcessorResponse $response */ 69 | $response = $HybridAuth->runProcessor('web/user/update', $data); 70 | if ($response->isError()) { 71 | $data['error.message'] = $response->getMessage(); 72 | foreach ($response->errors as $error) { 73 | $data['error.' . $error->field] = $error->message; 74 | } 75 | } 76 | $data['success'] = (int)!$response->isError(); 77 | } 78 | 79 | $add = array(); 80 | if ($services = $modx->user->getMany('Services')) { 81 | /** @var haUserService $service */ 82 | foreach ($services as $service) { 83 | $add = array_merge($add, $service->toArray(strtolower($service->get('provider') . '.'))); 84 | } 85 | } 86 | 87 | $url = $HybridAuth->getUrl(); 88 | $user = $modx->user->toArray(); 89 | $profile = $modx->user->Profile->toArray(); 90 | $data = array_merge( 91 | $user, 92 | $profile, 93 | $add, 94 | $data, 95 | array( 96 | 'login_url' => $url . 'login', 97 | 'logout_url' => $url . 'logout', 98 | 'providers' => $HybridAuth->getProvidersLinks($providerTpl, $activeProviderTpl), 99 | 'gravatar' => 'https://gravatar.com/avatar/' . md5(strtolower($profile['email'])), 100 | ) 101 | ); 102 | 103 | return $HybridAuth->getChunk($profileTpl, $data); 104 | -------------------------------------------------------------------------------- /core/components/hybridauth/elements/snippets/snippet.hybridauth.php: -------------------------------------------------------------------------------- 1 | error->reset(); 6 | if (!$modx->loadClass('hybridauth', MODX_CORE_PATH . 'components/hybridauth/model/hybridauth/', false, true)) { 7 | return; 8 | } 9 | $HybridAuth = new HybridAuth($modx, $scriptProperties); 10 | $HybridAuth->initialize($modx->context->key); 11 | 12 | if ($modx->error->hasError()) { 13 | return $modx->error->message; 14 | } // For compatibility with old snippet 15 | elseif (!empty($action)) { 16 | $tmp = strtolower($action); 17 | if ($tmp == 'getprofile' || $tmp == 'updateprofile') { 18 | return $modx->runSnippet('haProfile', $scriptProperties); 19 | } 20 | } 21 | 22 | if (empty($loginTpl)) { 23 | $loginTpl = 'tpl.HybridAuth.login'; 24 | } 25 | if (empty($logoutTpl)) { 26 | $logoutTpl = 'tpl.HybridAuth.logout'; 27 | } 28 | if (empty($providerTpl)) { 29 | $providerTpl = 'tpl.HybridAuth.provider'; 30 | } 31 | if (empty($activeProviderTpl)) { 32 | $activeProviderTpl = 'tpl.HybridAuth.provider.active'; 33 | } 34 | 35 | $url = $HybridAuth->getUrl(); 36 | $error = ''; 37 | if (!empty($_SESSION['HybridAuth']['error'])) { 38 | $error = $_SESSION['HybridAuth']['error']; 39 | unset($_SESSION['HybridAuth']['error']); 40 | } 41 | 42 | if ($modx->user->isAuthenticated($modx->context->key)) { 43 | $add = array(); 44 | if ($services = $modx->user->getMany('Services')) { 45 | /** @var haUserService $service */ 46 | foreach ($services as $service) { 47 | $add = array_merge($add, $service->toArray(strtolower($service->get('provider') . '.'))); 48 | } 49 | } 50 | 51 | $user = $modx->user->toArray(); 52 | $profile = $modx->user->Profile->toArray(); 53 | unset($profile['id']); 54 | $arr = array_merge( 55 | $user, 56 | $profile, 57 | $add, 58 | array( 59 | 'login_url' => $url . 'login', 60 | 'logout_url' => $url . 'logout', 61 | 'providers' => $HybridAuth->getProvidersLinks($providerTpl, $activeProviderTpl), 62 | 'error' => $error, 63 | 'gravatar' => 'https://gravatar.com/avatar/' . md5(strtolower($profile['email'])), 64 | ) 65 | ); 66 | 67 | return $HybridAuth->getChunk($logoutTpl, $arr); 68 | } else { 69 | $arr = array( 70 | 'login_url' => $url . 'login', 71 | 'logout_url' => $url . 'logout', 72 | 'providers' => $HybridAuth->getProvidersLinks($providerTpl, $activeProviderTpl), 73 | 'error' => $error, 74 | ); 75 | 76 | return $HybridAuth->getChunk($loginTpl, $arr); 77 | } 78 | -------------------------------------------------------------------------------- /core/components/hybridauth/lexicon/en/default.inc.php: -------------------------------------------------------------------------------- 1 | Gravatar'; 29 | 30 | $_lang['ha.services'] = 'Auth Providers'; 31 | $_lang['ha.services_tip'] = 'Here you can see what providers were used by this user to login on the website.'; 32 | $_lang['ha.service_avatar'] = 'Avatar'; 33 | $_lang['ha.service_createdon'] = 'Created'; 34 | $_lang['ha.service_provider'] = 'Provider'; 35 | $_lang['ha.service_identifier'] = 'Identifier'; 36 | $_lang['ha.service_displayname'] = 'Display Name'; 37 | $_lang['ha.service_email'] = 'Email'; 38 | 39 | $_lang['ha.service_remove'] = 'Unbind provider'; 40 | $_lang['ha.services_remove'] = 'Unbind providers'; 41 | $_lang['ha.service_remove_confirm'] = 'Are you sure you want to unbind this provider from profile of the user?'; 42 | $_lang['ha.services_remove_confirm'] = 'Are you sure you want to unbind this providers from profile of the user?'; 43 | 44 | $_lang['area_ha.main'] = 'Main'; 45 | $_lang['area_ha.keys'] = 'Keys'; 46 | $_lang['setting_ha.keys.Google'] = 'Keys for Google'; 47 | $_lang['setting_ha.keys.Google_desc'] = 'Add the application and generate the keys at this link: https://code.google.com/apis/console/.'; 48 | $_lang['setting_ha.keys.GitHub'] = 'Keys for GitHub'; 49 | $_lang['setting_ha.keys.GitHub_desc'] = 'Add the application and generate the keys at this link: https://github.com/settings/applications/new.'; 50 | $_lang['setting_ha.keys.Twitter'] = 'Keys for Twitter'; 51 | $_lang['setting_ha.keys.Twitter_desc'] = 'Add the application and generate the keys at this link: https://dev.twitter.com/apps/new.'; 52 | $_lang['setting_ha.keys.Yandex'] = 'Keys for Yandex'; 53 | $_lang['setting_ha.keys.Yandex_desc'] = 'Add the application and generate the keys at this link: https://oauth.yandex.ru/client/new.'; 54 | $_lang['setting_ha.keys.Facebook'] = 'Keys for Facebook'; 55 | $_lang['setting_ha.keys.Facebook_desc'] = 'Add the application and generate the keys at this link: https://developers.facebook.com/apps.'; 56 | $_lang['setting_ha.keys.Vkontakte'] = 'Keys for Vkontakte'; 57 | $_lang['setting_ha.keys.Vkontakte_desc'] = 'Add the application and generate the keys at this link: https://vk.com/editapp?act=create.'; 58 | 59 | $_lang['setting_ha.frontend_css'] = 'Styles of frontend'; 60 | $_lang['setting_ha.frontend_css_desc'] = 'Path to the file with styles of component. If you want to use your own styles - specify the path to it here, or clear and include them manually via the website template.'; 61 | $_lang['setting_ha.register_users'] = 'Register new'; 62 | $_lang['setting_ha.register_users_desc'] = 'This setting determines whether to create new users with authorization through HybridAuth.'; 63 | -------------------------------------------------------------------------------- /core/components/hybridauth/lexicon/en/properties.inc.php: -------------------------------------------------------------------------------- 1 | Gravatar'; 29 | 30 | $_lang['ha.services'] = 'Провайдеры авторизации'; 31 | $_lang['ha.services_tip'] = 'Здесь вы можете видеть, какие провайдеры используются для авторизации пользователя на сайте.'; 32 | $_lang['ha.service_avatar'] = 'Аватарка'; 33 | $_lang['ha.service_createdon'] = 'Дата создания'; 34 | $_lang['ha.service_provider'] = 'Провайдер'; 35 | $_lang['ha.service_identifier'] = 'Идентификатор'; 36 | $_lang['ha.service_displayname'] = 'Имя'; 37 | $_lang['ha.service_email'] = 'Email'; 38 | 39 | $_lang['ha.service_remove'] = 'Отвязать провайдера'; 40 | $_lang['ha.services_remove'] = 'Отвязать провайдеров'; 41 | $_lang['ha.service_remove_confirm'] = 'Вы уверены, что хотите отвязать этого провайдера от профиля пользователя?'; 42 | $_lang['ha.services_remove_confirm'] = 'Вы уверены, что хотите отвязать этих провайдеров от профиля пользователя?'; 43 | 44 | $_lang['area_ha.main'] = 'Основные'; 45 | $_lang['area_ha.keys'] = 'Ключи'; 46 | $_lang['setting_ha.keys.Google'] = 'Ключи для Google'; 47 | $_lang['setting_ha.keys.Google_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://code.google.com/apis/console/.'; 48 | $_lang['setting_ha.keys.GitHub'] = 'Ключи для GitHub'; 49 | $_lang['setting_ha.keys.GitHub_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://github.com/settings/applications/new.'; 50 | $_lang['setting_ha.keys.Twitter'] = 'Ключи для Twitter'; 51 | $_lang['setting_ha.keys.Twitter_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://dev.twitter.com/apps/new.'; 52 | $_lang['setting_ha.keys.Yandex'] = 'Ключи для Yandex'; 53 | $_lang['setting_ha.keys.Yandex_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://oauth.yandex.ru/client/new.'; 54 | $_lang['setting_ha.keys.Facebook'] = 'Ключи для Facebook'; 55 | $_lang['setting_ha.keys.Facebook_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://developers.facebook.com/apps.'; 56 | $_lang['setting_ha.keys.Vkontakte'] = 'Ключи для Vkontakte'; 57 | $_lang['setting_ha.keys.Vkontakte_desc'] = 'Добавить приложение и сгенерировать ключи можно по этой ссылке: https://vk.com/editapp?act=create.'; 58 | 59 | $_lang['setting_ha.frontend_css'] = 'Стили фронтенда'; 60 | $_lang['setting_ha.frontend_css_desc'] = 'Путь к файлу со стилями компонента. Если вы хотите использовать собственные стили - укажите путь к ним здесь, или очистите параметр и загрузите их вручную через шаблон сайта.'; 61 | $_lang['setting_ha.register_users'] = 'Регистрировать новых'; 62 | $_lang['setting_ha.register_users_desc'] = 'Эта настройка определяет, нужно ли создавать новых пользователей при авторизации через HybridAuth.'; 63 | -------------------------------------------------------------------------------- /core/components/hybridauth/lexicon/ru/properties.inc.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | $_lang['hybridauth'] = 'HybridAuth'; 12 | $_lang['ha_err_no_providers'] = 'Ви повинні вказати хоча б одного провайдера.'; 13 | $_lang['ha_err_not_logged_in'] = 'Ви повинні бути авторизовані для редагування свого профілю'; 14 | $_lang['ha_err_no_provider_keys'] = 'Не можу отримати ключі [[+provider]] з системних налаштувань. [[+provider]] не було активовано.'; 15 | 16 | $_lang['ha.username'] = 'Логін'; 17 | $_lang['ha.fullname'] = 'Ім’я користувача'; 18 | $_lang['ha.email'] = 'Email'; 19 | $_lang['ha.updateProfile'] = 'Оновити профіль'; 20 | $_lang['ha.profile_update_success'] = 'Профіль оновлено'; 21 | $_lang['ha.profile_update_error'] = 'Помилка при оновлені профілю'; 22 | $_lang['ha.logout'] = 'Вийти →'; 23 | $_lang['ha.save_profile'] = 'Зберегти профіль'; 24 | $_lang['ha.greeting'] = 'Ви авторизовані як '; 25 | $_lang['ha.providers_available'] = 'Доступні провайдери '; 26 | $_lang['ha.login_intro'] = 'Ви можете авторизуватись на сайті за допомоги: '; 27 | $_lang['ha.gravatar'] = 'Аватар'; 28 | $_lang['ha.gravatar_desc'] = 'Картинка завантажується з Gravatar'; 29 | 30 | $_lang['area_ha.main'] = 'Основні'; 31 | $_lang['area_ha.keys'] = 'Ключі'; 32 | $_lang['setting_ha.keys.Google'] = 'Ключі для Google'; 33 | $_lang['setting_ha.keys.Google_desc'] = 'Додати додаток та згенерувати ключі можна за цим посиланням: https://code.google.com/apis/console/. Про налаштування інших провайдерів можна прочитати в документації: http://hybridauth.sourceforge.net/userguide.html.'; 34 | $_lang['setting_ha.keys.Twitter'] = 'Ключі для Twitter'; 35 | $_lang['setting_ha.keys.Twitter_desc'] = 'Додати додаток та згенерувати ключі можна за цим посиланням: https://dev.twitter.com/apps/new. Про налаштування інших провайдерів можна прочитати в документації: http://hybridauth.sourceforge.net/userguide.html.'; 36 | $_lang['setting_ha.keys.Yandex'] = 'Ключі для Yandex'; 37 | $_lang['setting_ha.keys.Yandex_desc'] = 'Додати додаток та згенерувати ключі можна за цим посиланням: https://oauth.yandex.ru/client/new. Про налаштування інших провайдерів можна прочитати в документації: http://hybridauth.sourceforge.net/userguide.html.'; 38 | $_lang['setting_ha.keys.Facebook'] = 'Ключі для Facebook'; 39 | $_lang['setting_ha.keys.Facebook_desc'] = 'Додати додаток та згенерувати ключі можна за цим посиланням: https://developers.facebook.com/apps. Про налаштування інших провайдерів можна прочитати в документації: http://hybridauth.sourceforge.net/userguide.html.'; 40 | $_lang['setting_ha.keys.Vkontakte'] = 'Ключі для Vkontakte'; 41 | $_lang['setting_ha.keys.Vkontakte_desc'] = 'Додати додаток та згенерувати ключі можна за цим посиланням: http://vk.com/editapp?act=create. Про налаштування інших провайдерів можна прочитати в документації: http://hybridauth.sourceforge.net/userguide.html.'; 42 | 43 | $_lang['setting_ha.frontend_css'] = 'Стилі фронтенда'; 44 | $_lang['setting_ha.frontend_css_desc'] = 'Шлях до файлу зі стилями компонента. Якщо ви хочете використовувати власні стилі - вкажіть шлях до них тут, або очистіть параметр і завантажте їх вручну через шаблон сайту.'; 45 | $_lang['setting_ha.register_users'] = 'Реєструвати нових'; 46 | $_lang['setting_ha.register_users_desc'] = 'Цей параметр визначає, чи потрібно створювати нових користувачів при авторизації через HybridAuth.'; 47 | -------------------------------------------------------------------------------- /core/components/hybridauth/lexicon/uk/properties.inc.php: -------------------------------------------------------------------------------- 1 | modx = $modx; 20 | 21 | $corePath = MODX_CORE_PATH . 'components/hybridauth/'; 22 | $assetsUrl = MODX_ASSETS_URL . 'components/hybridauth/'; 23 | $this->modx->lexicon->load('hybridauth:default', 'core:user'); 24 | 25 | $this->config = array_merge([ 26 | 'corePath' => $corePath, 27 | 'assetsUrl' => $assetsUrl, 28 | 'modelPath' => $corePath . 'model/', 29 | 'processorsPath' => $corePath . 'processors/', 30 | 'jsUrl' => $assetsUrl . 'js/', 31 | 'cssUrl' => $assetsUrl . 'css/', 32 | 'connectorUrl' => $assetsUrl . 'connector.php', 33 | 34 | 'rememberme' => true, 35 | 'groups' => '', 36 | 'loginContext' => '', 37 | 'addContexts' => '', 38 | 'loginResourceId' => 0, 39 | 'logoutResourceId' => 0, 40 | 'providers' => '', 41 | ], $config); 42 | 43 | $this->loadHybridAuth(); 44 | $_SESSION['HybridAuth'][$this->modx->context->key] = $this->config; 45 | } 46 | 47 | 48 | /** 49 | * Custom exception handler for Hybrid_Auth 50 | * 51 | * @param Throwable $e 52 | */ 53 | public function exceptionHandler(Throwable $e) 54 | { 55 | $code = $e->getCode(); 56 | if ($code <= 6) { 57 | $level = modX::LOG_LEVEL_ERROR; 58 | } else { 59 | $level = modX::LOG_LEVEL_INFO; 60 | } 61 | 62 | $this->modx->log($level, '[HybridAuth] ' . $e->getMessage()); 63 | } 64 | 65 | 66 | /** 67 | * Initializes component into different contexts. 68 | * 69 | * @access public 70 | * 71 | * @param string $ctx The context to load. Defaults to web. 72 | * @param array $scriptProperties Properties for initialization. 73 | * 74 | * @return boolean 75 | */ 76 | public function initialize($ctx = 'web', $scriptProperties = []) 77 | { 78 | $this->config = array_merge($this->config, $scriptProperties); 79 | $this->config['ctx'] = $ctx; 80 | if (!empty($this->initialized[$ctx])) { 81 | return true; 82 | } 83 | switch ($ctx) { 84 | case 'mgr': 85 | break; 86 | default: 87 | $config = $this->makePlaceholders($this->config); 88 | if ($css = $this->modx->getOption('ha.frontend_css')) { 89 | $this->modx->regClientCSS(str_replace($config['pl'], $config['vl'], $css)); 90 | } 91 | $this->initialized[$ctx] = true; 92 | } 93 | 94 | return true; 95 | } 96 | 97 | 98 | /** 99 | * Loads HybridAuth adapters 100 | */ 101 | public function loadHybridAuth() 102 | { 103 | if (!class_exists('OAuth2')) { 104 | require_once MODX_CORE_PATH . 'components/hybridauth/vendor/autoload.php'; 105 | } 106 | 107 | if (!empty($this->config['providers'])) { 108 | $providers = array_map('trim', explode(',', $this->config['providers'])); 109 | } else { 110 | $providers = []; 111 | foreach ($this->modx->config as $option => $value) { 112 | if (strpos($option, 'ha.keys.') === 0) { 113 | $providers[] = substr($option, 8); 114 | } 115 | } 116 | } 117 | foreach ($providers as $provider) { 118 | if ($config = $this->modx->getOption('ha.keys.' . $provider)) { 119 | $config = json_decode($config, true); 120 | $class = '\Hybridauth\Provider\\' . $provider; 121 | if (is_array($config) && class_exists($class)) { 122 | if (!isset($config['keys'])) { 123 | $config = [ 124 | 'keys' => [ 125 | 'id' => $config['key'] ?? $config['id'], 126 | 'secret' => $config['secret'], 127 | ], 128 | ]; 129 | } 130 | 131 | try { 132 | $config['callback'] = $this->modx->getOption('site_url') . '?hauth.done=' . $provider; 133 | $this->adapters[$provider] = new $class($config); 134 | } catch (Exception $e) { 135 | $this->exceptionHandler($e); 136 | } 137 | } 138 | } 139 | } 140 | $_SESSION['HA'] = []; 141 | } 142 | 143 | 144 | /** 145 | * Checks and login user. Also creates/updated user services profiles 146 | * 147 | * @param string $provider Remote service to login 148 | */ 149 | public function Login($provider) 150 | { 151 | try { 152 | if (isset($this->adapters[$provider])) { 153 | /** @var OAuth2 $adapter */ 154 | $adapter = $this->adapters[$provider]; 155 | $adapter->authenticate(); 156 | } 157 | } catch (Exception $e) { 158 | $this->exceptionHandler($e); 159 | } 160 | 161 | if (empty($adapter) || !$adapter->isConnected()) { 162 | $this->Refresh('login'); 163 | return; 164 | } 165 | 166 | unset($_SESSION['HybridAuth']['error']); 167 | try { 168 | if ($profile = $adapter->getUserProfile()) { 169 | $profile = json_decode(json_encode($profile), true); 170 | } 171 | } catch (Exception $e) { 172 | $this->exceptionHandler($e); 173 | $this->Refresh('login'); 174 | } 175 | $profile['provider'] = $provider; 176 | 177 | 178 | /** @var haUserService $service */ 179 | $service = $this->modx->getObject('haUserService', [ 180 | 'identifier' => $profile['identifier'], 181 | 'provider' => $profile['provider'], 182 | ]); 183 | if (!$service) { 184 | // Adding new record to current user 185 | if ($this->modx->user->isAuthenticated($this->modx->context->key)) { 186 | $uid = $this->modx->user->id; 187 | $profile['internalKey'] = $uid; 188 | 189 | $response = $this->runProcessor('web/service/create', $profile); 190 | if ($response->isError()) { 191 | $msg = implode(', ', $response->getAllErrors()); 192 | $this->modx->log( 193 | modX::LOG_LEVEL_ERROR, 194 | '[HybridAuth] unable to save service profile for user ' . $uid . '. Message: ' . $msg 195 | ); 196 | $_SESSION['HybridAuth']['error'] = $msg; 197 | } 198 | } else { 199 | // Create a new user and add this record to him 200 | $username = !empty($profile['identifier']) ? 201 | trim($profile['identifier']) 202 | : md5(rand(8, 10)); 203 | if ($exists = $this->modx->getCount('modUser', ['username' => $username])) { 204 | for ($i = 1; $i <= 10; $i++) { 205 | $tmp = $username . $i; 206 | if (!$this->modx->getCount('modUser', ['username' => $tmp])) { 207 | $username = $tmp; 208 | break; 209 | } 210 | } 211 | } 212 | $arr = [ 213 | 'username' => $username, 214 | 'fullname' => !empty($profile['lastName']) 215 | ? $profile['firstName'] . ' ' . $profile['lastName'] 216 | : $profile['firstName'], 217 | 'dob' => !empty($profile['birthDay']) && !empty($profile['birthMonth']) && !empty($profile['birthYear']) 218 | ? $profile['birthYear'] . '-' . $profile['birthMonth'] . '-' . $profile['birthDay'] 219 | : '', 220 | 'email' => !empty($profile['emailVerified']) 221 | ? $profile['emailVerified'] 222 | : $profile['email'], 223 | 'photo' => !empty($profile['photoURL']) 224 | ? $profile['photoURL'] 225 | : '', 226 | 'website' => !empty($profile['webSiteURL']) 227 | ? $profile['webSiteURL'] 228 | : '', 229 | 'phone' => !empty($profile['phone']) 230 | ? $profile['phone'] 231 | : '', 232 | 'address' => !empty($profile['address']) 233 | ? $profile['address'] 234 | : '', 235 | 'country' => !empty($profile['country']) 236 | ? $profile['country'] 237 | : '', 238 | 'state' => !empty($profile['region']) 239 | ? $profile['region'] 240 | : '', 241 | 'city' => !empty($profile['city']) 242 | ? $profile['city'] 243 | : '', 244 | 'zip' => !empty($profile['zip']) 245 | ? $profile['zip'] 246 | : '', 247 | 'active' => 1, 248 | 'provider' => $profile, 249 | 'groups' => $this->config['groups'], 250 | ]; 251 | if (!$this->modx->getOption('ha.register_users', null, true)) { 252 | $_SESSION['HybridAuth']['error'] = $this->modx->lexicon('ha_register_disabled'); 253 | } else { 254 | $response = $this->runProcessor('web/user/create', $arr); 255 | if ($response->isError()) { 256 | $msg = implode(', ', $response->getAllErrors()); 257 | $this->modx->log( 258 | modX::LOG_LEVEL_ERROR, 259 | '[HybridAuth] Unable to create user ' . print_r($arr, 1) . '. Message: ' . $msg 260 | ); 261 | $_SESSION['HybridAuth']['error'] = $msg; 262 | } else { 263 | $login_data = [ 264 | 'username' => $response->response['object']['username'], 265 | 'password' => md5(rand()), 266 | 'rememberme' => $this->config['rememberme'], 267 | ]; 268 | $uid = $response->response['object']['id']; 269 | $profile['internalKey'] = $uid; 270 | $response = $this->runProcessor('web/service/create', $profile); 271 | if ($response->isError()) { 272 | $msg = implode(', ', $response->getAllErrors()); 273 | $this->modx->log( 274 | modX::LOG_LEVEL_ERROR, 275 | '[HybridAuth] unable to save service profile for user ' . $uid . '. Message: ' . $msg 276 | ); 277 | $_SESSION['HybridAuth']['error'] = $msg; 278 | } 279 | } 280 | } 281 | } 282 | } else { 283 | // Find and use connected MODX user 284 | if ($this->modx->user->isAuthenticated($this->modx->context->key)) { 285 | $uid = $this->modx->user->id; 286 | } else { 287 | $uid = $service->get('internalKey'); 288 | } 289 | 290 | /** @var modUser $user */ 291 | if ($user = $this->modx->getObject('modUser', $uid)) { 292 | $login_data = [ 293 | 'username' => $user->get('username'), 294 | 'password' => md5(rand()), 295 | 'rememberme' => $this->config['rememberme'], 296 | ]; 297 | $profile['id'] = $service->get('id'); 298 | $profile['internalKey'] = $uid; 299 | $response = $this->runProcessor('web/service/update', $profile); 300 | if ($response->isError()) { 301 | $msg = implode(', ', $response->getAllErrors()); 302 | $this->modx->log( 303 | modX::LOG_LEVEL_ERROR, 304 | '[HybridAuth] unable to update service profile for user ' . $uid . '. Message: ' . $msg 305 | ); 306 | $_SESSION['HybridAuth']['error'] = $msg; 307 | } 308 | } else { 309 | $service->remove(); 310 | $this->Login($provider); 311 | } 312 | } 313 | 314 | $this->modx->error->reset(); 315 | if ( 316 | empty($_SESSION['HybridAuth']['error']) 317 | && !$this->modx->user->isAuthenticated($this->modx->context->key) 318 | && !empty($login_data) 319 | ) { 320 | $_SESSION['HA']['verified'] = 1; 321 | if (!empty($this->config['loginContext'])) { 322 | $login_data['login_context'] = $this->config['loginContext']; 323 | } 324 | if (!empty($this->config['addContexts'])) { 325 | $login_data['add_contexts'] = $this->config['addContexts']; 326 | } 327 | 328 | // Login 329 | $_SESSION['HybridAuth']['verified'] = true; 330 | $response = $this->modx->runProcessor('security/login', $login_data); 331 | if ($response->isError()) { 332 | $msg = implode(', ', $response->getAllErrors()); 333 | $this->modx->log( 334 | modX::LOG_LEVEL_ERROR, 335 | '[HybridAuth] error login for user ' . $login_data['username'] . '. Message: ' . $msg 336 | ); 337 | $_SESSION['HybridAuth']['error'] = $msg; 338 | } 339 | } 340 | 341 | $this->Refresh('login'); 342 | } 343 | 344 | 345 | /** 346 | * Destroys all sessions 347 | * 348 | * @return void 349 | */ 350 | public function Logout() 351 | { 352 | try { 353 | /** @var OAuth2 $adapter */ 354 | foreach ($this->adapters as $adapter) { 355 | $adapter->disconnect(); 356 | } 357 | } catch (Exception $e) { 358 | $this->exceptionHandler($e); 359 | } 360 | 361 | $logout_data = []; 362 | if (!empty($this->config['loginContext'])) { 363 | $logout_data['login_context'] = $this->config['loginContext']; 364 | } 365 | if (!empty($this->config['addContexts'])) { 366 | $logout_data['add_contexts'] = $this->config['addContexts']; 367 | } 368 | 369 | $response = $this->modx->runProcessor('security/logout', $logout_data); 370 | if ($response->isError()) { 371 | $msg = implode(', ', $response->getAllErrors()); 372 | $this->modx->log( 373 | modX::LOG_LEVEL_ERROR, 374 | '[HybridAuth] logout error. Username: ' . $this->modx->user->get('username') . ', uid: ' . $msg 375 | ); 376 | $_SESSION['HybridAuth']['error'] = $msg; 377 | } 378 | $this->Refresh('logout'); 379 | } 380 | 381 | 382 | /** 383 | * Refreshes the current page. If set, can redirects user to logout/login resource. 384 | * 385 | * @param string $action The action to do 386 | * 387 | * @return void 388 | */ 389 | public function Refresh($action = '') 390 | { 391 | $url = ''; 392 | if ($action == 'login' && !empty($this->config['loginResourceId'])) { 393 | /** @var modResource $resource */ 394 | if ($resource = $this->modx->getObject('modResource', (int)$this->config['loginResourceId'])) { 395 | $url = $this->modx->makeUrl($resource->id, $resource->context_key, '', 'full'); 396 | } 397 | } elseif ($action == 'logout' && !empty($this->config['logoutResourceId'])) { 398 | /** @var modResource $resource */ 399 | if ($resource = $this->modx->getObject('modResource', (int)$this->config['logoutResourceId'])) { 400 | $url = $this->modx->makeUrl($resource->id, $resource->context_key, '', 'full'); 401 | } 402 | } 403 | 404 | if (empty($url)) { 405 | $request = preg_replace('#^' . $this->modx->getOption('base_url') . '#', '', $_SERVER['REQUEST_URI']); 406 | $url = $this->modx->getOption('site_url') . ltrim($request, '/'); 407 | if ($pos = strpos($url, '?')) { 408 | $arr = explode('&', substr($url, $pos + 1)); 409 | $url = substr($url, 0, $pos); 410 | if (count($arr) > 1) { 411 | foreach ($arr as $k => $v) { 412 | if ( 413 | preg_match( 414 | '#(action|provider|hauth.action|hauth.done|state|code|error|error_description)+#i', 415 | $v, 416 | $matches 417 | ) 418 | ) { 419 | unset($arr[$k]); 420 | } 421 | } 422 | if (!empty($arr)) { 423 | $url = $url . '?' . implode('&', $arr); 424 | } 425 | 426 | } 427 | } 428 | } 429 | 430 | $this->modx->sendRedirect($url); 431 | } 432 | 433 | 434 | /** 435 | * Returns working url 436 | * 437 | * @return mixed $url 438 | */ 439 | public function getUrl() 440 | { 441 | $request = preg_replace('#^' . $this->modx->getOption('base_url') . '#', '', $_SERVER['REQUEST_URI']); 442 | $url = $this->modx->getOption('site_url') . ltrim(rawurldecode($request), '/'); 443 | $url = preg_replace('#["\']#', '', strip_tags($url)); 444 | $url = preg_replace('#\[\[.*?\]\]#', '', $url); 445 | 446 | $url .= strpos($url, '?') 447 | ? '&hauth_action=' 448 | : '?hauth_action='; 449 | 450 | return $url; 451 | } 452 | 453 | 454 | /** 455 | * @param string $tpl1 456 | * @param string $tpl2 457 | * 458 | * @return string 459 | */ 460 | public function getProvidersLinks($tpl1 = 'tpl.HybridAuth.provider', $tpl2 = 'tpl.HybridAuth.provider.active') 461 | { 462 | if (empty($this->adapters)) { 463 | return ''; 464 | } 465 | 466 | $output = ''; 467 | $url = $this->getUrl(); 468 | $active = []; 469 | 470 | if ($this->modx->user->isAuthenticated($this->modx->context->key)) { 471 | $c = $this->modx->newQuery('haUserService', ['internalKey' => $this->modx->user->id]); 472 | $c->select('provider'); 473 | if ($c->prepare() && $c->stmt->execute()) { 474 | while ($row = $c->stmt->fetch(PDO::FETCH_COLUMN)) { 475 | $active[] = strtolower($row); 476 | }; 477 | } 478 | } 479 | 480 | foreach ($this->adapters as $provider => $adapter) { 481 | $pls = [ 482 | 'login_url' => $url . 'login', 483 | 'logout_url' => $url . 'logout', 484 | 'unbind_url' => $url . 'unbind', 485 | 'provider' => strtolower($provider), 486 | 'title' => $provider, 487 | ]; 488 | 489 | $output .= !in_array($pls['provider'], $active) 490 | ? $this->getChunk($tpl1, $pls) 491 | : $this->getChunk($tpl2, $pls); 492 | } 493 | 494 | return $output; 495 | } 496 | 497 | 498 | /** 499 | * Sanitizes a string 500 | * 501 | * @param string $string The string to sanitize 502 | * @param integer $length The length of sanitized string 503 | * 504 | * @return string The sanitized string. 505 | */ 506 | public function Sanitize($string = '', $length = 0) 507 | { 508 | $expr = '#[^-_a-zа-яёЁ0-9@\s\.\,\:\/\\\]+#iu'; 509 | $sanitized = trim(preg_replace($expr, '', $string)); 510 | 511 | return !empty($length) 512 | ? substr($sanitized, 0, $length) 513 | : $sanitized; 514 | } 515 | 516 | 517 | /** 518 | * Shorthand for load and run an processor in this component 519 | * 520 | * @param string $action 521 | * @param array $scriptProperties 522 | * 523 | * @return mixed 524 | */ 525 | public function runProcessor($action = '', $scriptProperties = []) 526 | { 527 | $this->modx->error->reset(); 528 | 529 | return $this->modx->runProcessor( 530 | $action, 531 | $scriptProperties, 532 | [ 533 | 'processors_path' => $this->config['processorsPath'], 534 | ] 535 | ); 536 | } 537 | 538 | 539 | /** 540 | * Transform array to placeholders 541 | * 542 | * @param array $array 543 | * @param string $plPrefix 544 | * @param string $prefix 545 | * @param string $suffix 546 | * @param bool $uncacheable 547 | * 548 | * @return array 549 | */ 550 | public function makePlaceholders( 551 | array $array = [], 552 | $plPrefix = '', 553 | $prefix = '[[+', 554 | $suffix = ']]', 555 | $uncacheable = true 556 | ) 557 | { 558 | $result = ['pl' => [], 'vl' => []]; 559 | 560 | $uncached_prefix = str_replace('[[', '[[!', $prefix); 561 | foreach ($array as $k => $v) { 562 | if (is_array($v)) { 563 | $result = array_merge_recursive( 564 | $result, 565 | $this->makePlaceholders($v, $plPrefix . $k . '.', $prefix, $suffix, $uncacheable) 566 | ); 567 | } else { 568 | $pl = $plPrefix . $k; 569 | $result['pl'][$pl] = $prefix . $pl . $suffix; 570 | $result['vl'][$pl] = $v; 571 | if ($uncacheable) { 572 | $result['pl']['!' . $pl] = $uncached_prefix . $pl . $suffix; 573 | $result['vl']['!' . $pl] = $v; 574 | } 575 | } 576 | } 577 | 578 | return $result; 579 | } 580 | 581 | 582 | /** 583 | * @param $tpl 584 | * @param array $params 585 | * 586 | * @return mixed|string 587 | */ 588 | public function getChunk($tpl, $params = []) 589 | { 590 | /** @var pdoTools $pdoTools */ 591 | if (class_exists('pdoTools') && $pdoTools = $this->modx->getService('pdoTools')) { 592 | return $pdoTools->getChunk($tpl, $params); 593 | } 594 | 595 | return $this->modx->getChunk($tpl, $params); 596 | } 597 | 598 | 599 | /** 600 | * @param modManagerController $controller 601 | * @param modUser $user 602 | */ 603 | public function regManagerTab($controller, $user) 604 | { 605 | $this->config['user_id'] = $user->id; 606 | $controller->addLexiconTopic('hybridauth:default'); 607 | $controller->addCss($this->config['cssUrl'] . 'mgr/main.css'); 608 | $controller->addCss($this->config['cssUrl'] . 'mgr/bootstrap.buttons.css'); 609 | $controller->addJavascript($this->config['jsUrl'] . 'mgr/hybridauth.js'); 610 | $controller->addJavascript($this->config['jsUrl'] . 'mgr/misc/utils.js'); 611 | $controller->addJavascript($this->config['jsUrl'] . 'mgr/widgets/service.grid.js'); 612 | $controller->addHtml(''); 613 | } 614 | } 615 | -------------------------------------------------------------------------------- /core/components/hybridauth/model/hybridauth/metadata.mysql.php: -------------------------------------------------------------------------------- 1 | 5 | array( 6 | 0 => 'haUserService', 7 | ), 8 | ); 9 | 10 | $this->map['modUser']['composites']['Services'] = array( 11 | 'class' => 'haUserService', 12 | 'local' => 'id', 13 | 'foreign' => 'internalKey', 14 | 'cardinality' => 'many', 15 | 'owner' => 'local', 16 | ); 17 | -------------------------------------------------------------------------------- /core/components/hybridauth/model/hybridauth/mysql/hauserservice.class.php: -------------------------------------------------------------------------------- 1 | 'hybridauth', 5 | 'version' => '1.0', 6 | 'table' => 'ha_user_services', 7 | 'extends' => 'xPDOSimpleObject', 8 | 'tableMeta' => 9 | array( 10 | 'engine' => 'InnoDB', 11 | ), 12 | 'fields' => 13 | array( 14 | 'internalKey' => null, 15 | 'identifier' => null, 16 | 'provider' => null, 17 | 'createdon' => null, 18 | 'websiteurl' => null, 19 | 'profileurl' => null, 20 | 'photourl' => null, 21 | 'displayname' => null, 22 | 'description' => null, 23 | 'firstname' => null, 24 | 'lastname' => null, 25 | 'gender' => null, 26 | 'language' => null, 27 | 'age' => null, 28 | 'birthday' => null, 29 | 'birthmonth' => null, 30 | 'birthyear' => null, 31 | 'email' => null, 32 | 'emailverified' => null, 33 | 'phone' => null, 34 | 'address' => null, 35 | 'country' => null, 36 | 'region' => null, 37 | 'city' => null, 38 | 'zip' => null, 39 | 'extended' => null, 40 | ), 41 | 'fieldMeta' => 42 | array( 43 | 'internalKey' => 44 | array( 45 | 'dbtype' => 'int', 46 | 'precision' => '10', 47 | 'phptype' => 'integer', 48 | 'null' => false, 49 | 'attributes' => 'unsigned', 50 | 'index' => 'unique', 51 | 'indexgrp' => 'unique_fields', 52 | ), 53 | 'identifier' => 54 | array( 55 | 'dbtype' => 'varchar', 56 | 'precision' => '100', 57 | 'phptype' => 'string', 58 | 'null' => false, 59 | ), 60 | 'provider' => 61 | array( 62 | 'dbtype' => 'varchar', 63 | 'precision' => '50', 64 | 'phptype' => 'string', 65 | 'null' => false, 66 | 'index' => 'unique', 67 | 'indexgrp' => 'unique_fields', 68 | ), 69 | 'createdon' => 70 | array( 71 | 'dbtype' => 'datetime', 72 | 'phptype' => 'datetime', 73 | ), 74 | 'websiteurl' => 75 | array( 76 | 'dbtype' => 'varchar', 77 | 'precision' => '255', 78 | 'phptype' => 'string', 79 | 'null' => true, 80 | ), 81 | 'profileurl' => 82 | array( 83 | 'dbtype' => 'varchar', 84 | 'precision' => '255', 85 | 'phptype' => 'string', 86 | 'null' => true, 87 | ), 88 | 'photourl' => 89 | array( 90 | 'dbtype' => 'varchar', 91 | 'precision' => '255', 92 | 'phptype' => 'string', 93 | 'null' => true, 94 | ), 95 | 'displayname' => 96 | array( 97 | 'dbtype' => 'varchar', 98 | 'precision' => '100', 99 | 'phptype' => 'string', 100 | 'null' => true, 101 | ), 102 | 'description' => 103 | array( 104 | 'dbtype' => 'text', 105 | 'phptype' => 'string', 106 | 'null' => true, 107 | ), 108 | 'firstname' => 109 | array( 110 | 'dbtype' => 'varchar', 111 | 'precision' => '100', 112 | 'phptype' => 'string', 113 | 'null' => true, 114 | ), 115 | 'lastname' => 116 | array( 117 | 'dbtype' => 'varchar', 118 | 'precision' => '100', 119 | 'phptype' => 'string', 120 | 'null' => true, 121 | ), 122 | 'gender' => 123 | array( 124 | 'dbtype' => 'varchar', 125 | 'precision' => '50', 126 | 'phptype' => 'string', 127 | 'null' => true, 128 | ), 129 | 'language' => 130 | array( 131 | 'dbtype' => 'varchar', 132 | 'precision' => '50', 133 | 'phptype' => 'string', 134 | 'null' => true, 135 | ), 136 | 'age' => 137 | array( 138 | 'dbtype' => 'tinyint', 139 | 'precision' => '3', 140 | 'phptype' => 'integer', 141 | 'null' => true, 142 | ), 143 | 'birthday' => 144 | array( 145 | 'dbtype' => 'tinyint', 146 | 'precision' => '2', 147 | 'phptype' => 'integer', 148 | 'null' => true, 149 | ), 150 | 'birthmonth' => 151 | array( 152 | 'dbtype' => 'tinyint', 153 | 'precision' => '2', 154 | 'phptype' => 'integer', 155 | 'null' => true, 156 | ), 157 | 'birthyear' => 158 | array( 159 | 'dbtype' => 'smallint', 160 | 'precision' => '4', 161 | 'phptype' => 'integer', 162 | 'null' => true, 163 | ), 164 | 'email' => 165 | array( 166 | 'dbtype' => 'varchar', 167 | 'precision' => '100', 168 | 'phptype' => 'string', 169 | 'null' => true, 170 | ), 171 | 'emailverified' => 172 | array( 173 | 'dbtype' => 'varchar', 174 | 'precision' => '100', 175 | 'phptype' => 'string', 176 | 'null' => true, 177 | ), 178 | 'phone' => 179 | array( 180 | 'dbtype' => 'varchar', 181 | 'precision' => '100', 182 | 'phptype' => 'string', 183 | 'null' => true, 184 | ), 185 | 'address' => 186 | array( 187 | 'dbtype' => 'varchar', 188 | 'precision' => '255', 189 | 'phptype' => 'string', 190 | 'null' => true, 191 | ), 192 | 'country' => 193 | array( 194 | 'dbtype' => 'varchar', 195 | 'precision' => '100', 196 | 'phptype' => 'string', 197 | 'null' => true, 198 | ), 199 | 'region' => 200 | array( 201 | 'dbtype' => 'varchar', 202 | 'precision' => '100', 203 | 'phptype' => 'string', 204 | 'null' => true, 205 | ), 206 | 'city' => 207 | array( 208 | 'dbtype' => 'varchar', 209 | 'precision' => '100', 210 | 'phptype' => 'string', 211 | 'null' => true, 212 | ), 213 | 'zip' => 214 | array( 215 | 'dbtype' => 'varchar', 216 | 'precision' => '25', 217 | 'phptype' => 'string', 218 | 'null' => true, 219 | ), 220 | 'extended' => 221 | array( 222 | 'dbtype' => 'text', 223 | 'phptype' => 'json', 224 | 'null' => true, 225 | 'index' => 'fulltext', 226 | ), 227 | ), 228 | 'indexes' => 229 | array( 230 | 'unique_fields' => 231 | array( 232 | 'alias' => 'unique_fields', 233 | 'primary' => false, 234 | 'unique' => true, 235 | 'type' => 'BTREE', 236 | 'columns' => 237 | array( 238 | 'internalKey' => 239 | array( 240 | 'length' => '', 241 | 'collation' => 'A', 242 | 'null' => false, 243 | ), 244 | 'provider' => 245 | array( 246 | 'length' => '', 247 | 'collation' => 'A', 248 | 'null' => false, 249 | ), 250 | ), 251 | ), 252 | ), 253 | 'aggregates' => 254 | array( 255 | 'User' => 256 | array( 257 | 'class' => 'modUser', 258 | 'local' => 'internalKey', 259 | 'foreign' => 'id', 260 | 'cardinality' => 'one', 261 | 'owner' => 'foreign', 262 | ), 263 | ), 264 | ); 265 | -------------------------------------------------------------------------------- /core/components/hybridauth/model/schema/hybridauth.mysql.schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/mgr/service/getlist.class.php: -------------------------------------------------------------------------------- 1 | getProperty('user_id'); 19 | if ($userId > 0) { 20 | $c->where( 21 | array( 22 | 'internalKey' => $userId, 23 | ) 24 | ); 25 | } 26 | 27 | return $c; 28 | } 29 | 30 | 31 | /** 32 | * @param xPDOQuery $c 33 | * 34 | * @return xPDOQuery 35 | */ 36 | public function prepareQueryAfterCount(xPDOQuery $c) 37 | { 38 | $c->select($this->modx->getSelectColumns($this->classKey, $this->classKey)); 39 | $c->select( 40 | array( 41 | 'IF(emailverified IS NULL OR LENGTH(emailverified) = 0, email, emailverified) AS email', 42 | ) 43 | ); 44 | 45 | return $c; 46 | } 47 | 48 | 49 | /** 50 | * @param xPDOObject $object 51 | * 52 | * @return array 53 | */ 54 | public function prepareRow(xPDOObject $object) 55 | { 56 | $array = $object->toArray(); 57 | $array['hash'] = md5(strtolower($array['email'])); 58 | 59 | $array['actions'] = array(); 60 | // Remove 61 | $array['actions'][] = array( 62 | 'cls' => '', 63 | 'icon' => 'icon icon-trash-o action-red', 64 | 'title' => $this->modx->lexicon('ha.service_remove'), 65 | 'multiple' => $this->modx->lexicon('ha.services_remove'), 66 | 'action' => 'removeItem', 67 | 'button' => true, 68 | 'menu' => true, 69 | ); 70 | 71 | return $array; 72 | } 73 | } 74 | 75 | return 'haUserServiceGetListProcessor'; 76 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/mgr/service/remove.class.php: -------------------------------------------------------------------------------- 1 | checkPermissions()) { 16 | return $this->failure($this->modx->lexicon('access_denied')); 17 | } 18 | $ids = $this->modx->fromJSON($this->getProperty('ids')); 19 | if (empty($ids)) { 20 | return $this->failure($this->modx->lexicon('ha_service_err_ns')); 21 | } 22 | foreach ($ids as $id) { 23 | /** @var haUserService $object */ 24 | if (!$object = $this->modx->getObject($this->classKey, (int)$id)) { 25 | return $this->failure($this->modx->lexicon('ha_service_err_nf')); 26 | } 27 | $object->remove(); 28 | } 29 | 30 | return $this->success(); 31 | } 32 | } 33 | 34 | return 'haUserServiceRemoveProcessor'; 35 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/web/service/create.class.php: -------------------------------------------------------------------------------- 1 | getProperties(); 16 | 17 | foreach ($properties as $k => $v) { 18 | $k = strtolower($k); 19 | if (is_array($v)) { 20 | foreach ($v as &$v2) { 21 | $v2 = $this->modx->stripTags($v2); 22 | } 23 | $properties[$k] = $v; 24 | } else { 25 | $properties[$k] = $this->modx->stripTags($v); 26 | } 27 | } 28 | $properties['createdon'] = date('Y-m-d H:i:m'); 29 | 30 | if (empty($properties['internalKey'])) { 31 | $this->addFieldError('internalKey', $this->modx->lexicon('field_required')); 32 | } 33 | if (empty($properties['provider'])) { 34 | $this->addFieldError('provider', $this->modx->lexicon('field_required')); 35 | } 36 | 37 | $this->setProperties($properties); 38 | 39 | return !$this->hasErrors(); 40 | } 41 | } 42 | 43 | return 'haUserServiceCreateProcessor'; 44 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/web/service/remove.class.php: -------------------------------------------------------------------------------- 1 | getProperty('provider'); 17 | $this->object = $this->modx->getObject($this->classKey, array( 18 | 'internalKey' => $this->modx->user->id, 19 | 'provider' => $provider, 20 | )); 21 | 22 | if (empty($this->object)) { 23 | return $this->modx->lexicon($this->objectType . '_err_nfs'); 24 | } 25 | 26 | return true; 27 | } 28 | } 29 | 30 | return 'haUserServiceRemoveProcessor'; 31 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/web/service/update.class.php: -------------------------------------------------------------------------------- 1 | getProperties(); 16 | 17 | foreach ($properties as $k => $v) { 18 | $k = strtolower($k); 19 | if (is_array($v)) { 20 | foreach ($v as &$v2) { 21 | $v2 = $this->modx->stripTags($v2); 22 | } 23 | $properties[$k] = $v; 24 | } else { 25 | $properties[$k] = $this->modx->stripTags($v); 26 | } 27 | } 28 | 29 | if (empty($properties['internalKey'])) { 30 | $this->addFieldError('internalKey', $this->modx->lexicon('field_required')); 31 | } 32 | if (empty($properties['provider'])) { 33 | $this->addFieldError('provider', $this->modx->lexicon('field_required')); 34 | } 35 | 36 | $this->setProperties($properties); 37 | 38 | return !$this->hasErrors(); 39 | } 40 | } 41 | 42 | return 'haUserServiceUpdateProcessor'; 43 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/web/user/create.class.php: -------------------------------------------------------------------------------- 1 | modx->getOption('ha.register_users', null, true)) { 21 | return $this->modx->lexicon('ha_register_disabled'); 22 | } 23 | 24 | $this->setProperty('passwordnotifymethod', 's'); 25 | 26 | if (!$this->getProperty('username')) { 27 | $this->addFieldError('username', $this->modx->lexicon('field_required')); 28 | } 29 | 30 | if (!$this->getProperty('email')) { 31 | $this->setProperty('email', 'emptyemail@nomail.com'); 32 | } 33 | 34 | return parent::beforeSet(); 35 | } 36 | 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function setUserGroups() 42 | { 43 | $memberships = array(); 44 | $groups = $this->getProperty('groups', null); 45 | if ($groups !== null) { 46 | $groups = explode(',', $groups); 47 | $groupsAdded = array(); 48 | $idx = 0; 49 | foreach ($groups as $tmp) { 50 | @list($group, $role) = explode(':', $tmp); 51 | if (in_array($group, $groupsAdded)) { 52 | continue; 53 | } 54 | if (empty($role)) { 55 | $role = 1; 56 | } 57 | 58 | if ($tmp = $this->modx->getObject('modUserGroup', array('name' => $group))) { 59 | $gid = $tmp->get('id'); 60 | /** @var modUserGroupMember $membership */ 61 | $membership = $this->modx->newObject('modUserGroupMember'); 62 | $membership->set('user_group', $gid); 63 | $membership->set('role', $role); 64 | $membership->set('member', $this->object->get('id')); 65 | $membership->set('rank', $idx); 66 | $membership->save(); 67 | $memberships[] = $membership; 68 | $groupsAdded[] = $group; 69 | $idx++; 70 | } 71 | } 72 | } 73 | 74 | return $memberships; 75 | } 76 | 77 | 78 | /** 79 | * @return modUserProfile 80 | */ 81 | public function addProfile() 82 | { 83 | $this->profile = $this->modx->newObject('modUserProfile'); 84 | $this->profile->fromArray($this->getProperties()); 85 | $this->profile->set('blocked', $this->getProperty('blocked', false)); 86 | $this->object->addOne($this->profile, 'Profile'); 87 | 88 | return $this->profile; 89 | } 90 | 91 | 92 | /** 93 | * @return bool 94 | */ 95 | public function beforeSave() 96 | { 97 | $beforeSave = parent::beforeSave(); 98 | 99 | if ($this->profile->get('email') == 'emptyemail@nomail.com') { 100 | $this->profile->set('email', ''); 101 | } 102 | 103 | return $beforeSave; 104 | } 105 | 106 | } 107 | 108 | return 'haUserCreateProcessor'; 109 | -------------------------------------------------------------------------------- /core/components/hybridauth/processors/web/user/update.class.php: -------------------------------------------------------------------------------- 1 | setProperty('id', $this->modx->user->id); 21 | 22 | return parent::initialize(); 23 | } 24 | 25 | 26 | /** 27 | * @return bool 28 | */ 29 | public function beforeSet() 30 | { 31 | $fields = $this->getProperty('requiredFields', ''); 32 | if (!empty($fields) && is_array($fields)) { 33 | foreach ($fields as $field) { 34 | $tmp = trim($this->getProperty($field, null)); 35 | if ($field == 'email' && !preg_match('/^[^@а-яА-Я]+@[^@а-яА-Я]+(?addFieldError('email', $this->modx->lexicon('user_err_not_specified_email')); 37 | } else { 38 | if (empty($tmp)) { 39 | $this->addFieldError($field, $this->modx->lexicon('field_required')); 40 | } 41 | } 42 | } 43 | } 44 | 45 | return parent::beforeSet(); 46 | } 47 | 48 | } 49 | 50 | return 'haUserUpdateProcessor'; 51 | -------------------------------------------------------------------------------- /core/components/hybridauth/providers/ModxPro.php: -------------------------------------------------------------------------------- 1 | apiRequest('profile', 'POST')); 28 | 29 | if (!$data->exists('identifier')) { 30 | throw new Exception('User profile request failed! ModxPro returned an invalid response.'); 31 | } 32 | 33 | $userProfile = new Profile(); 34 | $userProfile->identifier = $data->get('identifier'); 35 | $userProfile->email = $data->get('email'); 36 | $userProfile->displayName = $data->get('displayName'); 37 | $userProfile->photoURL = $data->get('photoURL'); 38 | $userProfile->webSiteURL = $data->get('webSiteURL'); 39 | $userProfile->profileURL = $data->get('profileUrl'); 40 | $userProfile->phone = $data->get('phone'); 41 | $userProfile->address = $data->get('address'); 42 | $userProfile->region = $data->get('region'); 43 | $userProfile->city = $data->get('city'); 44 | $userProfile->zip = $data->get('zip'); 45 | 46 | return $userProfile; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/components/hybridauth/providers/Yandex.php: -------------------------------------------------------------------------------- 1 | apiRequest('', 'GET')); 28 | if (!$data->exists('id')) { 29 | throw new Exception('User profile request failed! ModxPro returned an invalid response.'); 30 | } 31 | $userProfile = new Profile(); 32 | 33 | $userProfile->identifier = $data->get('id'); 34 | $userProfile->firstName = $data->get('real_name'); 35 | $userProfile->lastName = $data->get('family_name'); 36 | $userProfile->displayName = $data->get('display_name'); 37 | $userProfile->photoURL = 'http://upics.yandex.net/' . $userProfile->identifier . '/normal'; 38 | $userProfile->profileURL = ''; 39 | $userProfile->gender = (int)$data->get('sex') == 'female'; 40 | $userProfile->email = 41 | $userProfile->emailVerified = $data->get('default_email'); 42 | 43 | if ($dob = $data->get('birthday')) { 44 | list($userProfile->birthYear, $userProfile->birthMonth, $userProfile->birthDay) = explode('-', $dob); 45 | } 46 | 47 | return $userProfile; 48 | } 49 | } 50 | 51 | --------------------------------------------------------------------------------