Advanced Access Manager - Version 6.6.0

Version Description

  • Fixed Bug: No ability to "allow" API Route https://github.com/aamplugin/advanced-access-manager/issues/131
  • Fixed Bug: Passwordless login sets cookie that might logout issues https://github.com/aamplugin/advanced-access-manager/issues/129
  • Fixed Bug: AAM does not retain selected time https://github.com/aamplugin/advanced-access-manager/issues/133
  • Changed: Logout user automatically if JWT token is revoked https://github.com/aamplugin/advanced-access-manager/issues/118
  • Changed: Enhance Backend Menu service https://github.com/aamplugin/advanced-access-manager/issues/114
  • Added New: The ability to export/import access policies https://github.com/aamplugin/advanced-access-manager/issues/130
  • Added New: Add roles claim to the issued JWT token https://github.com/aamplugin/advanced-access-manager/issues/100
  • Added New: [aam-login] shortcode that renders AAM secure login form https://github.com/aamplugin/advanced-access-manager/issues/90
Download this release

Release Info

Developer vasyltech
Plugin Icon 128x128 Advanced Access Manager
Version 6.6.0
Comparing to
See all releases

Code changes from version 6.5.4 to 6.6.0

aam.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Plugin Name: Advanced Access Manager
5
  * Description: Collection of features to manage your WordPress website authentication, authorization and monitoring
6
- * Version: 6.5.4
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
@@ -264,7 +264,7 @@ if (defined('ABSPATH')) {
264
  //define few common constants
265
  define('AAM_MEDIA', plugins_url('/media', __FILE__));
266
  define('AAM_KEY', 'advanced-access-manager');
267
- define('AAM_VERSION', '6.5.4');
268
  define('AAM_BASEDIR', __DIR__);
269
 
270
  //load vendor
3
  /**
4
  * Plugin Name: Advanced Access Manager
5
  * Description: Collection of features to manage your WordPress website authentication, authorization and monitoring
6
+ * Version: 6.6.0
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
264
  //define few common constants
265
  define('AAM_MEDIA', plugins_url('/media', __FILE__));
266
  define('AAM_KEY', 'advanced-access-manager');
267
+ define('AAM_VERSION', '6.6.0');
268
  define('AAM_BASEDIR', __DIR__);
269
 
270
  //load vendor
application/Backend/Feature/Main/Route.php CHANGED
@@ -5,15 +5,16 @@
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
8
- *
9
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * WordPress API manager
14
  *
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Backend_Feature_Main_Route
19
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
@@ -84,15 +85,18 @@ class AAM_Backend_Feature_Main_Route
84
  *
85
  * @return string
86
  *
 
 
 
87
  * @access public
88
- * @version 6.0.0
89
  */
90
  public function save()
91
  {
92
  $type = $this->getFromPost('type');
93
  $route = $this->getFromPost('route');
94
  $method = $this->getFromPost('method');
95
- $value = $this->getFromPost('value');
96
 
97
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
98
  $id = strtolower("{$type}|{$route}|{$method}");
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
 
 
8
  */
9
 
10
  /**
11
  * WordPress API manager
12
  *
13
+ * @since 6.6.0 Fixed https://github.com/aamplugin/advanced-access-manager/issues/131
14
+ * @since 6.0.0 Initial implementation of the class
15
+ *
16
  * @package AAM
17
+ * @version 6.6.0
18
  */
19
  class AAM_Backend_Feature_Main_Route
20
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
85
  *
86
  * @return string
87
  *
88
+ * @since 6.6.0 Fixed https://github.com/aamplugin/advanced-access-manager/issues/131
89
+ * @since 6.0.0 Initial implementation of the method
90
+ *
91
  * @access public
92
+ * @version 6.6.0
93
  */
94
  public function save()
95
  {
96
  $type = $this->getFromPost('type');
97
  $route = $this->getFromPost('route');
98
  $method = $this->getFromPost('method');
99
+ $value = $this->getFromPost('value', FILTER_VALIDATE_BOOLEAN);
100
 
101
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
102
  $id = strtolower("{$type}|{$route}|{$method}");
application/Backend/Feature/Settings/Manager.php CHANGED
@@ -10,13 +10,14 @@
10
  /**
11
  * Backend Settings area abstract manager
12
  *
 
13
  * @since 6.5.0 https://github.com/aamplugin/advanced-access-manager/issues/109
14
  * https://github.com/aamplugin/advanced-access-manager/issues/106
15
  * @since 6.2.0 Added Import/Export functionality
16
  * @since 6.0.0 Initial implementation of the class
17
  *
18
  * @package AAM
19
- * @version 6.5.0
20
  */
21
  class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
22
  {
@@ -124,11 +125,12 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
124
  *
125
  * @return string
126
  *
 
127
  * @since 6.3.0 Optimized AAM_Core_API::getOption call
128
  * @since 6.2.0 Initial implementation of the method
129
  *
130
  * @access public
131
- * @version 6.3.0
132
  */
133
  public function exportSettings()
134
  {
@@ -152,13 +154,14 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
152
  foreach($groups as $group) {
153
  switch($group) {
154
  case 'settings':
155
- $dataset['settings'] = AAM_Core_API::getOption(
 
156
  AAM_Core_AccessSettings::DB_OPTION, array()
157
- );
158
  break;
159
 
160
  case 'config':
161
- $dataset['config'] = AAM_Core_API::getOption(
162
  AAM_Core_Config::DB_OPTION, array()
163
  );
164
  $dataset['configpress'] = AAM_Core_API::getOption(
@@ -182,13 +185,113 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
182
  ));
183
  }
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  /**
186
  * Import AAM settings
187
  *
188
  * @return string
189
  *
 
 
 
190
  * @access public
191
- * @version 6.2.0
192
  */
193
  public function importSettings()
194
  {
@@ -217,6 +320,10 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
217
  );
218
  break;
219
 
 
 
 
 
220
  default:
221
  break;
222
  }
@@ -234,6 +341,109 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
234
  return wp_json_encode($response);
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  /**
238
  * Register settings UI manager
239
  *
10
  /**
11
  * Backend Settings area abstract manager
12
  *
13
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/130
14
  * @since 6.5.0 https://github.com/aamplugin/advanced-access-manager/issues/109
15
  * https://github.com/aamplugin/advanced-access-manager/issues/106
16
  * @since 6.2.0 Added Import/Export functionality
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
+ * @version 6.6.0
21
  */
22
  class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
23
  {
125
  *
126
  * @return string
127
  *
128
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/130
129
  * @since 6.3.0 Optimized AAM_Core_API::getOption call
130
  * @since 6.2.0 Initial implementation of the method
131
  *
132
  * @access public
133
+ * @version 6.6.0
134
  */
135
  public function exportSettings()
136
  {
154
  foreach($groups as $group) {
155
  switch($group) {
156
  case 'settings':
157
+ $this->_prepareSettings(
158
+ AAM_Core_API::getOption(
159
  AAM_Core_AccessSettings::DB_OPTION, array()
160
+ ), $dataset);
161
  break;
162
 
163
  case 'config':
164
+ $dataset['config'] = AAM_Core_API::getOption(
165
  AAM_Core_Config::DB_OPTION, array()
166
  );
167
  $dataset['configpress'] = AAM_Core_API::getOption(
185
  ));
186
  }
187
 
188
+ /**
189
+ * Prepare exported access settings
190
+ *
191
+ * Change the way access policies are exported
192
+ *
193
+ * @param array $settings
194
+ * @param array &$dataset
195
+ *
196
+ * @return void
197
+ *
198
+ * @access private
199
+ * @version 6.0.0
200
+ */
201
+ private function _prepareSettings($settings, &$dataset)
202
+ {
203
+ $policies = array();
204
+
205
+ // Extract all defined policies from roles
206
+ if (isset($settings['role'])) {
207
+ foreach($settings['role'] as $role => &$data) {
208
+ if (isset($data['policy'])) {
209
+ $policies = $this->_preparePolicyList(
210
+ 'role', $role, $data['policy'], $policies
211
+ );
212
+ unset($data['policy']);
213
+ }
214
+ }
215
+ }
216
+
217
+ // Extract all defined policies from users
218
+ if (isset($settings['user'])) {
219
+ foreach($settings['user'] as $user => &$data) {
220
+ if (isset($data['policy'])) {
221
+ $policies = $this->_preparePolicyList(
222
+ 'user', $user, $data['policy'], $policies
223
+ );
224
+ unset($data['policy']);
225
+ }
226
+ }
227
+ }
228
+
229
+ // Extract all defined policies from visitors
230
+ if (isset($settings['visitor']['policy'])) {
231
+ $policies = $this->_preparePolicyList(
232
+ 'visitor', null, $settings['visitor']['policy'], $policies
233
+ );
234
+ unset($settings['visitor']['policy']);
235
+ }
236
+
237
+ // Extract all defined policies from default
238
+ if (isset($settings['default']['policy'])) {
239
+ $policies = $this->_preparePolicyList(
240
+ 'default', null, $settings['default']['policy'], $policies
241
+ );
242
+ unset($settings['default']['policy']);
243
+ }
244
+
245
+ $dataset['settings'] = $settings;
246
+ $dataset['policies'] = $policies;
247
+ }
248
+
249
+ /**
250
+ * Prepare collection of policies
251
+ *
252
+ * @param string $type
253
+ * @param mixed $id
254
+ * @param array $settings
255
+ * @param array $policies
256
+ *
257
+ * @return array
258
+ *
259
+ * @access private
260
+ * @version 6.0.0
261
+ */
262
+ private function _preparePolicyList($type, $id, $settings, $policies)
263
+ {
264
+ foreach($settings as $policyId => $effect) {
265
+ if (!isset($policies[$policyId])) {
266
+ $p = get_post($policyId);
267
+
268
+ if (is_a($p, 'WP_Post')) { // Only existing policies
269
+ $policies[$policyId] = array(
270
+ 'policy' => wp_json_encode(json_decode($p->post_content)),
271
+ 'title' => $p->post_title,
272
+ 'description' => $p->post_excerpt,
273
+ 'assignee' => array()
274
+ );
275
+ }
276
+ }
277
+
278
+ $assignee = (!empty($id) ? "{$type}:{$id}" : $type);
279
+ $policies[$policyId]['assignee'][$assignee] = $effect;
280
+ }
281
+
282
+ return $policies;
283
+ }
284
+
285
  /**
286
  * Import AAM settings
287
  *
288
  * @return string
289
  *
290
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/130
291
+ * @since 6.2.0 Initial implementation of the method
292
+ *
293
  * @access public
294
+ * @version 6.6.0
295
  */
296
  public function importSettings()
297
  {
320
  );
321
  break;
322
 
323
+ case 'policies':
324
+ $this->_importPolicies($settings);
325
+ break;
326
+
327
  default:
328
  break;
329
  }
341
  return wp_json_encode($response);
342
  }
343
 
344
+ /**
345
+ * Import policies
346
+ *
347
+ * @param array $policies
348
+ *
349
+ * @return void
350
+ *
351
+ * @access private
352
+ * @version 6.6.0
353
+ */
354
+ private function _importPolicies($policies)
355
+ {
356
+ foreach($policies as $p) {
357
+ $pid = $this->_isExistingPolicy($p);
358
+
359
+ if ($pid === false) {
360
+ $pid = wp_insert_post(array(
361
+ 'post_title' => $p['title'],
362
+ 'post_content' => $p['policy'],
363
+ 'post_type' => AAM_Service_AccessPolicy::POLICY_CPT,
364
+ 'post_status' => 'publish',
365
+ 'post_excerpt' => $p['description']
366
+ ));
367
+ }
368
+
369
+ if (!is_wp_error($pid)) {
370
+ foreach($p['assignee'] as $s => $effect) {
371
+ $this->_applyPolicyToSubject($s, $pid, $effect);
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Check if the same policy already exists
379
+ *
380
+ * @param array $policy
381
+ *
382
+ * @return boolean|int
383
+ *
384
+ * @access private
385
+ * @version 6.6.0
386
+ */
387
+ private function _isExistingPolicy($policy)
388
+ {
389
+ $existing = false;
390
+
391
+ $found = get_page_by_title(
392
+ $policy['title'], OBJECT, AAM_Service_AccessPolicy::POLICY_CPT
393
+ );
394
+
395
+ if (!is_null($found)) {
396
+ foreach((is_array($found) ? $found : array($found)) as $p) {
397
+ $title = $p->post_title;
398
+ $json = wp_json_encode(json_decode($p->post_content));
399
+
400
+ if ($title === $policy['title'] && $json === $policy['policy']) {
401
+ $existing = $p->ID;
402
+ }
403
+ }
404
+ }
405
+
406
+ return $existing;
407
+ }
408
+
409
+ /**
410
+ * Apply policy to provided subject
411
+ *
412
+ * @param string $s
413
+ * @param int $policyId
414
+ * @param boolean $effect
415
+ *
416
+ * @return string|null
417
+ *
418
+ * @access protected
419
+ */
420
+ private function _applyPolicyToSubject($s, $policyId, $effect = true)
421
+ {
422
+ $error = null;
423
+
424
+ if ($s === 'visitor') {
425
+ $subject = AAM::api()->getVisitor();
426
+ } elseif ($s === 'default') {
427
+ $subject = AAM::api()->getDefault();
428
+ } elseif (strpos($s, 'role:') === 0) {
429
+ $subject = AAM::api()->getRole(substr($s, 5));
430
+ } elseif (strpos($s, 'user:') === 0) {
431
+ $uid = substr($s, 5);
432
+ $subject = AAM::api()->getUser(($uid === 'current') ? null : $uid);
433
+ } else {
434
+ $error = sprintf(__('Failed applying to %s', AAM_KEY), $s);
435
+ $subject = null;
436
+ }
437
+
438
+ if ($subject !== null) {
439
+ $subject->getObject(
440
+ AAM_Core_Object_Policy::OBJECT_TYPE, null, true
441
+ )->updateOptionItem($policyId, $effect)->save();
442
+ }
443
+
444
+ return $error;
445
+ }
446
+
447
  /**
448
  * Register settings UI manager
449
  *
application/Backend/View.php CHANGED
@@ -13,11 +13,12 @@
13
  * This class is used to manage all AAM UI templates and interaction of the UI with
14
  * AAM backend core
15
  *
 
16
  * @since 6.0.5 Removed prepareIframeWPAssetsURL method
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
- * @version 6.0.0
21
  */
22
  class AAM_Backend_View
23
  {
@@ -78,14 +79,17 @@ class AAM_Backend_View
78
  *
79
  * @return string
80
  *
 
 
 
81
  * @access public
82
- * @version 6.0.0
83
  */
84
  public static function loadTemplate($file_path, $params = null)
85
  {
86
  ob_start();
87
 
88
- require_once $file_path;
89
  $content = ob_get_contents();
90
 
91
  ob_end_clean();
13
  * This class is used to manage all AAM UI templates and interaction of the UI with
14
  * AAM backend core
15
  *
16
+ * @since 6.6.0 Allow partial to be loaded more than once
17
  * @since 6.0.5 Removed prepareIframeWPAssetsURL method
18
  * @since 6.0.0 Initial implementation of the class
19
  *
20
  * @package AAM
21
+ * @version 6.6.0
22
  */
23
  class AAM_Backend_View
24
  {
79
  *
80
  * @return string
81
  *
82
+ * @since 6.6.0 Fixed the way the partial is loaded
83
+ * @since 6.0.0 Initial implementation of the method
84
+ *
85
  * @access public
86
+ * @version 6.6.0
87
  */
88
  public static function loadTemplate($file_path, $params = null)
89
  {
90
  ob_start();
91
 
92
+ require $file_path;
93
  $content = ob_get_contents();
94
 
95
  ob_end_clean();
application/Backend/tmpl/partial/login-form.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (defined('AAM_KEY')) { ?>
2
+ <?php if (!is_user_logged_in()) { ?>
3
+ <div id="aam-login-error-<?php echo $params->id; ?>" style="display: none; margin-bottom: 15px; border-left: 4px solid #dc3232; padding: 6px;"></div>
4
+
5
+ <div id="login-form-<?php echo $params->id; ?>">
6
+ <p>
7
+ <label for="user_login"><?php echo __('Username or Email Address', AAM_KEY); ?><br>
8
+ <input id="aam-login-username-<?php echo $params->id; ?>" class="input login-input" type="text" />
9
+ </label>
10
+ </p>
11
+
12
+ <p>
13
+ <label for="user_pass"><?php echo __('Password', AAM_KEY); ?><br>
14
+ <input id="aam-login-password-<?php echo $params->id; ?>" class="input login-input" type="password" />
15
+ </label>
16
+ </p>
17
+
18
+ <?php do_action('login_form'); ?>
19
+
20
+ <p class="forgetmenot">
21
+ <label for="aam-login-remember-<?php echo $params->id; ?>">
22
+ <input id="aam-login-remember-<?php echo $params->id; ?>" value="forever" type="checkbox" /> <?php echo __('Remember Me', AAM_KEY); ?>
23
+ </label>
24
+ </p>
25
+
26
+ <p class="submit">
27
+ <input class="button button-primary button-large" id="aam-login-submit-<?php echo $params->id; ?>" value="<?php echo __('Log In', AAM_KEY); ?>" type="submit" />
28
+ <input id="aam-login-redirect-<?php echo $params->id; ?>" value="<?php echo $params->redirect; ?>" type="hidden" />
29
+ </p>
30
+ </div>
31
+
32
+ <p>
33
+ <?php
34
+ if (get_option('users_can_register')) {
35
+ $registration_url = sprintf('<a href="%s">%s</a>', esc_url(wp_registration_url()), __('Register', AAM_KEY));
36
+ echo apply_filters('register', $registration_url);
37
+ echo esc_html(apply_filters('login_link_separator', ' | '));
38
+ }
39
+ ?>
40
+ <a href="<?php echo esc_url(wp_lostpassword_url()); ?>"><?php echo __('Lost your password?', AAM_KEY); ?></a>
41
+ </p>
42
+ <script>
43
+ (function() {
44
+ var c = document.getElementById("aam-login-submit-<?php echo $params->id; ?>"),
45
+ b = document.getElementById("aam-login-username-<?php echo $params->id; ?>"),
46
+ d = document.getElementById("aam-login-password-<?php echo $params->id; ?>");
47
+
48
+ if (b) b.addEventListener("keyup", function(a) { 13 === a.which && c.click() });
49
+ if (d) d.addEventListener("keyup", function(a) { 13 === a.which && c.click() });
50
+
51
+ c && c.addEventListener("click", function() {
52
+ c.disabled = !0;
53
+ var a = new XMLHttpRequest;
54
+ a.addEventListener("readystatechange", function() {
55
+ if (4 === this.readyState) {
56
+ c.disabled = !1;
57
+ var a = JSON.parse(this.responseText);
58
+ if (200 === this.status) a.redirect ? location.href = a.redirect : location.reload();
59
+ else {
60
+ var b = document.getElementById("aam-login-error-<?php echo $params->id; ?>");
61
+ b.innerHTML = a.reason;
62
+ b.style.display = "block"
63
+ }
64
+ }
65
+ });
66
+ a.open("POST", "<?php echo get_rest_url(null, 'aam/v2/authenticate'); ?>");
67
+ a.setRequestHeader("Content-Type", "application/json");
68
+ a.setRequestHeader("Accept", "application/json");
69
+ a.send(JSON.stringify({
70
+ username: document.getElementById("aam-login-username-<?php echo $params->id; ?>").value,
71
+ password: document.getElementById("aam-login-password-<?php echo $params->id; ?>").value,
72
+ redirect: document.getElementById("aam-login-redirect-<?php echo $params->id; ?>").value,
73
+ remember: document.getElementById("aam-login-remember-<?php echo $params->id; ?>").checked,
74
+ returnAuthCookies: true
75
+ }))
76
+ })
77
+ })();
78
+ </script>
79
+
80
+ <?php } else { ?>
81
+ <div style="display: table; width: 100%;">
82
+ <div style="display:table-cell; width: 30%; text-align: center; vertical-align: middle;">
83
+ <?php echo get_avatar(AAM::getUser()->ID, 50); ?>
84
+ </div>
85
+ <div style="display:table-cell;">
86
+ <?php if (AAM_Core_API::isAAMCapabilityAllowed('aam_access_dashboard')) { ?>
87
+ <a href="<?php echo esc_url(get_admin_url()); ?>"><?php echo __('Dashboard', AAM_KEY); ?></a><br />
88
+ <a href="<?php echo esc_url(get_admin_url(null, 'profile.php')); ?>"><?php echo __('Edit My Profile', AAM_KEY); ?></a><br />
89
+ <?php } ?>
90
+ <a href="<?php echo esc_url(wp_logout_url()); ?>"><?php echo __('Log Out', AAM_KEY); ?></a>
91
+ </div>
92
+ </div>
93
+ <?php } ?>
94
+ <?php }
application/Backend/tmpl/service/menu.php CHANGED
@@ -1,4 +1,11 @@
1
- <?php /** @version 6.0.0 */ ?>
 
 
 
 
 
 
 
2
 
3
  <?php if (defined('AAM_KEY')) { ?>
4
  <div class="aam-feature" id="admin_menu-content">
@@ -6,7 +13,7 @@
6
  <div class="row">
7
  <div class="col-xs-12">
8
  <p class="aam-info">
9
- <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access to the backend main menu for [%s]. For more information check %sHow to manage WordPress backend menu%s.', 'b', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/article/how-to-manage-wordpress-backend-menu" target="_blank">', '</a>'); ?>
10
  </p>
11
  </div>
12
  </div>
@@ -22,19 +29,17 @@
22
 
23
  <div class="panel-group" id="admin-menu" role="tablist" aria-multiselectable="true">
24
  <?php
25
- $first = false;
26
- $object = AAM_Backend_Subject::getInstance()->getObject(AAM_Core_Object_Menu::OBJECT_TYPE);
27
- $menuList = $this->getMenu();
28
 
29
- if (!empty($menuList)) {
30
- foreach ($menuList as $i => $menu) {
31
- ?>
32
- <div class="panel panel-default">
33
  <div class="panel-heading" role="tab" id="menu-<?php echo $i; ?>-heading">
34
  <h4 class="panel-title">
35
- <a role="button" data-toggle="collapse" data-parent="#admin-menu" href="#menu-<?php echo $i; ?>" aria-controls="menu-<?php echo $i; ?>" <?php if (!$first) {
36
- echo 'aria-expanded="true"';
37
- } ?>>
38
  <?php echo $menu['name']; ?> <small class="aam-menu-capability"><?php echo $menu['capability']; ?></small>
39
  </a>
40
  <?php if ($menu['checked']) { ?>
@@ -46,9 +51,9 @@
46
  </div>
47
 
48
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) {
49
- echo ' in';
50
- $first = true;
51
- } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
52
  <div class="panel-body">
53
  <?php if ($menu['id'] != 'menu-index.php') { ?>
54
  <div class="row aam-inner-tab">
@@ -106,7 +111,7 @@
106
  </div>
107
  </div>
108
  <?php }
109
- } else { ?>
110
  <div class="row">
111
  <div class="col-xs-12">
112
  <p class="aam-notification">
@@ -173,4 +178,4 @@
173
  </div>
174
  </div>
175
  </div>
176
- <?php }
1
+ <?php
2
+ /**
3
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/114
4
+ * @since 6.0.0 Initial implementation of the template
5
+ *
6
+ * @version 6.6.0
7
+ * */
8
+ ?>
9
 
10
  <?php if (defined('AAM_KEY')) { ?>
11
  <div class="aam-feature" id="admin_menu-content">
13
  <div class="row">
14
  <div class="col-xs-12">
15
  <p class="aam-info">
16
+ <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access to the backend main menu for [%s]. Any menu that is lighter, indicates that [%s] does not have capability to access it. For more information check %sHow to manage WordPress backend menu%s.', 'b', 'b', 'b'), AAM_Backend_Subject::getInstance()->getName(), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/article/how-to-manage-wordpress-backend-menu" target="_blank">', '</a>'); ?>
17
  </p>
18
  </div>
19
  </div>
29
 
30
  <div class="panel-group" id="admin-menu" role="tablist" aria-multiselectable="true">
31
  <?php
32
+ $first = false;
33
+ $object = AAM_Backend_Subject::getInstance()->getObject(AAM_Core_Object_Menu::OBJECT_TYPE);
34
+ $menuList = $this->getMenu();
35
 
36
+ if (!empty($menuList)) {
37
+ foreach ($menuList as $i => $menu) {
38
+ ?>
39
+ <div class="panel panel-default" style="opacity: <?php echo AAM_Backend_Subject::getInstance()->hasCapability($menu['capability']) ? 1 : '0.5'; ?>">
40
  <div class="panel-heading" role="tab" id="menu-<?php echo $i; ?>-heading">
41
  <h4 class="panel-title">
42
+ <a role="button" data-toggle="collapse" data-parent="#admin-menu" href="#menu-<?php echo $i; ?>" aria-controls="menu-<?php echo $i; ?>" <?php if (!$first) { echo 'aria-expanded="true"'; } ?>>
 
 
43
  <?php echo $menu['name']; ?> <small class="aam-menu-capability"><?php echo $menu['capability']; ?></small>
44
  </a>
45
  <?php if ($menu['checked']) { ?>
51
  </div>
52
 
53
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) {
54
+ echo ' in';
55
+ $first = true;
56
+ } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
57
  <div class="panel-body">
58
  <?php if ($menu['id'] != 'menu-index.php') { ?>
59
  <div class="row aam-inner-tab">
111
  </div>
112
  </div>
113
  <?php }
114
+ } else { ?>
115
  <div class="row">
116
  <div class="col-xs-12">
117
  <p class="aam-notification">
178
  </div>
179
  </div>
180
  </div>
181
+ <?php }
application/Backend/tmpl/widget/login-frontend.php CHANGED
@@ -1,111 +1,27 @@
1
- <?php /** @version 6.0.4 */ ?>
2
-
3
- <?php if (defined('AAM_KEY')) { ?>
4
- <?php
5
- echo $this->args['before_widget'];
6
-
7
- if (!is_user_logged_in()) {
8
- echo $this->args['before_title'];
9
- echo apply_filters('widget_title', $this->args['login-title'], $this->args, $this->id_base);
10
- echo $this->args['after_title'];
11
- } elseif (is_user_logged_in()) {
12
- echo $this->args['before_title'];
13
- echo str_replace('%username%', AAM::getUser()->display_name, $this->args['user-title']);
14
- echo $this->args['after_title'];
15
- }
16
- ?>
17
-
18
- <?php if (!is_user_logged_in()) { ?>
19
- <div id="aam-login-error" style="display: none; margin-bottom: 15px; border-left: 4px solid #dc3232; padding: 6px;"></div>
20
-
21
- <div id="<?php echo $this->get_field_id('loginform'); ?>">
22
- <p>
23
- <label for="user_login"><?php echo __('Username or Email Address', AAM_KEY); ?><br>
24
- <input id="aam-login-username" class="input login-input" type="text" />
25
- </label>
26
- </p>
27
-
28
- <p>
29
- <label for="user_pass"><?php echo __('Password', AAM_KEY); ?><br>
30
- <input id="aam-login-password" class="input login-input" type="password" />
31
- </label>
32
- </p>
33
-
34
- <?php do_action('login_form'); ?>
35
-
36
- <p class="forgetmenot">
37
- <label for="rememberme">
38
- <input id="aam-login-remember" value="forever" type="checkbox" /> <?php echo __('Remember Me', AAM_KEY); ?>
39
- </label>
40
- </p>
41
-
42
- <p class="submit">
43
- <input class="button button-primary button-large" id="aam-login-submit" value="<?php echo __('Log In', AAM_KEY); ?>" type="submit" />
44
- <input id="aam-login-redirect" value="<?php echo $this->args['redirect']; ?>" type="hidden" />
45
- </p>
46
- </div>
47
-
48
- <p id="<?php echo $this->get_field_id('nav'); ?>">
49
- <?php
50
- if (get_option('users_can_register')) {
51
- $registration_url = sprintf('<a href="%s">%s</a>', esc_url(wp_registration_url()), __('Register'));
52
- echo apply_filters('register', $registration_url);
53
- echo esc_html(apply_filters('login_link_separator', ' | '));
54
- }
55
- ?>
56
- <a href="<?php echo esc_url(wp_lostpassword_url()); ?>"><?php echo __('Lost your password?', AAM_KEY); ?></a>
57
- </p>
58
- <script>
59
- (function() {
60
- var c = document.getElementById("aam-login-submit"),
61
- b = document.getElementsByClassName("login-input");
62
- if (b.length)
63
- for (var d = 0; d < b.length; d++) b[d].addEventListener("keyup", function(a) {
64
- 13 === a.which && c.click()
65
- });
66
- c && c.addEventListener("click", function() {
67
- c.disabled = !0;
68
- var a = new XMLHttpRequest;
69
- a.addEventListener("readystatechange", function() {
70
- if (4 === this.readyState) {
71
- c.disabled = !1;
72
- var a = JSON.parse(this.responseText);
73
- if (200 === this.status) a.redirect ? location.href = a.redirect : location.reload();
74
- else {
75
- var b = document.getElementById("aam-login-error");
76
- b.innerHTML = a.reason;
77
- b.style.display = "block"
78
- }
79
- }
80
- });
81
- a.open("POST", "<?php echo get_rest_url(null, 'aam/v2/authenticate'); ?>");
82
- a.setRequestHeader("Content-Type", "application/json");
83
- a.setRequestHeader("Accept", "application/json");
84
- a.send(JSON.stringify({
85
- username: document.getElementById("aam-login-username").value,
86
- password: document.getElementById("aam-login-password").value,
87
- redirect: document.getElementById("aam-login-redirect").value,
88
- remember: document.getElementById("aam-login-remember").checked,
89
- returnAuthCookies: true
90
- }))
91
- })
92
- })();
93
- </script>
94
-
95
- <?php } else { ?>
96
- <div style="display: table; width: 100%;">
97
- <div style="display:table-cell; width: 30%; text-align: center; vertical-align: middle;">
98
- <?php echo get_avatar(AAM::getUser()->ID, 50); ?>
99
- </div>
100
- <div style="display:table-cell;">
101
- <?php if (AAM_Core_API::isAAMCapabilityAllowed('aam_access_dashboard')) { ?>
102
- <a href="<?php echo esc_url(get_admin_url()); ?>"><?php echo __('Dashboard', AAM_KEY); ?></a><br />
103
- <a href="<?php echo esc_url(get_admin_url(null, 'profile.php')); ?>"><?php echo __('Edit My Profile', AAM_KEY); ?></a><br />
104
- <?php } ?>
105
- <a href="<?php echo esc_url(wp_logout_url()); ?>"><?php echo __('Log Out', AAM_KEY); ?></a>
106
- </div>
107
- </div>
108
- <?php } ?>
109
-
110
- <?php echo $this->args['after_widget']; ?>
111
- <?php }
1
+ <?php /**
2
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/90
3
+ * @since 6.0.4 Initial implementation of the template
4
+ *
5
+ * @version 6.6.0
6
+ * */
7
+
8
+ if (defined('AAM_KEY')) {
9
+ echo $this->args['before_widget'];
10
+
11
+ if (!is_user_logged_in()) {
12
+ echo $this->args['before_title'];
13
+ echo apply_filters('widget_title', $this->args['login-title'], $this->args, $this->id_base);
14
+ echo $this->args['after_title'];
15
+ } elseif (is_user_logged_in()) {
16
+ echo $this->args['before_title'];
17
+ echo str_replace('%username%', AAM::getUser()->display_name, $this->args['user-title']);
18
+ echo $this->args['after_title'];
19
+ }
20
+
21
+ echo AAM_Backend_View::loadPartial('login-form', array(
22
+ 'id' => $this->get_field_id('loginform'),
23
+ 'redirect' => $this->args['redirect']
24
+ ));
25
+
26
+ echo $this->args['after_widget'];
27
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
application/Service/Jwt.php CHANGED
@@ -10,6 +10,9 @@
10
  /**
11
  * JWT Token service
12
  *
 
 
 
13
  * @since 6.5.2 Fixed https://github.com/aamplugin/advanced-access-manager/issues/117
14
  * @since 6.5.0 Enhanced https://github.com/aamplugin/advanced-access-manager/issues/99
15
  * Fixed https://github.com/aamplugin/advanced-access-manager/issues/98
@@ -21,7 +24,7 @@
21
  * @since 6.0.0 Initial implementation of the class
22
  *
23
  * @package AAM
24
- * @version 6.5.2
25
  */
26
  class AAM_Service_Jwt
27
  {
@@ -94,13 +97,14 @@ class AAM_Service_Jwt
94
  *
95
  * @return void
96
  *
 
97
  * @since 6.4.0 Added the ability to issue refreshable token through API.
98
  * Enhanced https://github.com/aamplugin/advanced-access-manager/issues/71
99
  * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/25
100
  * @since 6.0.0 Initial implementation of the method
101
  *
102
  * @access protected
103
- * @version 6.4.0
104
  */
105
  protected function initializeHooks()
106
  {
@@ -139,26 +143,10 @@ class AAM_Service_Jwt
139
  return $args;
140
  });
141
  add_filter('aam_auth_response_filter', array($this, 'prepareLoginResponse'), 10, 2);
142
- add_action('set_logged_in_cookie', array($this, 'setJwtCookie'), 10, 6);
143
 
144
  // WP Core current user definition
145
  add_filter('determine_current_user', array($this, 'determineUser'), PHP_INT_MAX);
146
 
147
- // Delete JWT cookie if it is set
148
- add_action('wp_logout', function() {
149
- if ($this->getFromCookie('aam_jwt_token')) {
150
- setcookie(
151
- 'aam_jwt_token',
152
- null,
153
- time() - 1,
154
- COOKIEPATH,
155
- COOKIE_DOMAIN,
156
- is_ssl(),
157
- true
158
- );
159
- }
160
- });
161
-
162
  // Fetch specific claim from the JWT token if present
163
  add_filter('aam_get_jwt_claim', array($this, 'getJwtClaim'), 20, 2);
164
 
@@ -398,11 +386,12 @@ class AAM_Service_Jwt
398
  *
399
  * @return array
400
  *
 
401
  * @since 6.4.0 Added the ability to issue refreshable token
402
  * @since 6.0.0 Initial implementation of the method
403
  *
404
  * @access public
405
- * @version 6.4.0
406
  */
407
  public function prepareLoginResponse(array $response, WP_REST_Request $request)
408
  {
@@ -422,6 +411,16 @@ class AAM_Service_Jwt
422
  }
423
  }
424
 
 
 
 
 
 
 
 
 
 
 
425
  $jwt = $this->issueToken($response['user']->ID, null, null, $refreshable);
426
 
427
  $response['jwt'] = array(
@@ -538,8 +537,11 @@ class AAM_Service_Jwt
538
  *
539
  * @return bool
540
  *
 
 
 
541
  * @access public
542
- * @version 6.0.0
543
  */
544
  public function revokeUserToken($userId, $token)
545
  {
@@ -548,6 +550,13 @@ class AAM_Service_Jwt
548
  foreach($this->getTokenRegistry($userId) as $item) {
549
  if ($token !== $item) {
550
  $filtered[] = $item;
 
 
 
 
 
 
 
551
  }
552
  }
553
 
@@ -674,39 +683,6 @@ class AAM_Service_Jwt
674
  }
675
  }
676
 
677
- /**
678
- * Set custom cookie with JWT
679
- *
680
- * This can be used later by services like Access Policy to dynamically
681
- * evaluate conditions based on claims
682
- *
683
- * @param string $logged_in_cookie
684
- * @param int $expire
685
- *
686
- * @return void
687
- *
688
- * @access public
689
- * @version 6.0.0
690
- */
691
- public function setJwtCookie($logged_in_cookie, $expire)
692
- {
693
- if (apply_filters('send_auth_cookies', true)) {
694
- $token = $this->extractToken();
695
-
696
- if (!empty($token)) {
697
- setcookie(
698
- 'aam_jwt_token',
699
- $token->jwt,
700
- $expire,
701
- COOKIEPATH,
702
- COOKIE_DOMAIN,
703
- is_ssl(),
704
- true
705
- );
706
- }
707
- }
708
- }
709
-
710
  /**
711
  * Extract JWT token from the request
712
  *
10
  /**
11
  * JWT Token service
12
  *
13
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/129
14
+ * https://github.com/aamplugin/advanced-access-manager/issues/100
15
+ * https://github.com/aamplugin/advanced-access-manager/issues/118
16
  * @since 6.5.2 Fixed https://github.com/aamplugin/advanced-access-manager/issues/117
17
  * @since 6.5.0 Enhanced https://github.com/aamplugin/advanced-access-manager/issues/99
18
  * Fixed https://github.com/aamplugin/advanced-access-manager/issues/98
24
  * @since 6.0.0 Initial implementation of the class
25
  *
26
  * @package AAM
27
+ * @version 6.6.0
28
  */
29
  class AAM_Service_Jwt
30
  {
97
  *
98
  * @return void
99
  *
100
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/129
101
  * @since 6.4.0 Added the ability to issue refreshable token through API.
102
  * Enhanced https://github.com/aamplugin/advanced-access-manager/issues/71
103
  * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/25
104
  * @since 6.0.0 Initial implementation of the method
105
  *
106
  * @access protected
107
+ * @version 6.6.0
108
  */
109
  protected function initializeHooks()
110
  {
143
  return $args;
144
  });
145
  add_filter('aam_auth_response_filter', array($this, 'prepareLoginResponse'), 10, 2);
 
146
 
147
  // WP Core current user definition
148
  add_filter('determine_current_user', array($this, 'determineUser'), PHP_INT_MAX);
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  // Fetch specific claim from the JWT token if present
151
  add_filter('aam_get_jwt_claim', array($this, 'getJwtClaim'), 20, 2);
152
 
386
  *
387
  * @return array
388
  *
389
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/100
390
  * @since 6.4.0 Added the ability to issue refreshable token
391
  * @since 6.0.0 Initial implementation of the method
392
  *
393
  * @access public
394
+ * @version 6.6.0
395
  */
396
  public function prepareLoginResponse(array $response, WP_REST_Request $request)
397
  {
411
  }
412
  }
413
 
414
+ // Include also roles
415
+ if ($request->get_param('includeRoles') === true) {
416
+ add_filter('aam_jwt_claims_filter', function($claims) {
417
+ $user = get_user_by('ID', $claims['userId']);
418
+ $claims['roles'] = $user->roles;
419
+
420
+ return $claims;
421
+ });
422
+ }
423
+
424
  $jwt = $this->issueToken($response['user']->ID, null, null, $refreshable);
425
 
426
  $response['jwt'] = array(
537
  *
538
  * @return bool
539
  *
540
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/118
541
+ * @since 6.0.0 Initial implementation of the method
542
+ *
543
  * @access public
544
+ * @version 6.6.0
545
  */
546
  public function revokeUserToken($userId, $token)
547
  {
550
  foreach($this->getTokenRegistry($userId) as $item) {
551
  if ($token !== $item) {
552
  $filtered[] = $item;
553
+ } else {
554
+ // Also delete user session if any is active. The downside here is
555
+ // that if user logged in with different token, he still is going to
556
+ // be logged out because AAM does not track the token that user used
557
+ // to login
558
+ $sessions = WP_Session_Tokens::get_instance($userId);
559
+ $sessions->destroy_all();
560
  }
561
  }
562
 
683
  }
684
  }
685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
686
  /**
687
  * Extract JWT token from the request
688
  *
application/Service/Shortcode.php CHANGED
@@ -5,15 +5,16 @@
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
8
- *
9
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * AAM custom shortcodes service
14
  *
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Service_Shortcode
19
  {
@@ -61,8 +62,11 @@ class AAM_Service_Shortcode
61
  *
62
  * @return void
63
  *
 
 
 
64
  * @access protected
65
- * @version 6.0.0
66
  */
67
  protected function initializeHooks()
68
  {
@@ -72,6 +76,11 @@ class AAM_Service_Shortcode
72
 
73
  return $shortcode->process();
74
  });
 
 
 
 
 
75
  }
76
  }
77
 
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
 
 
8
  */
9
 
10
  /**
11
  * AAM custom shortcodes service
12
  *
13
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/90
14
+ * @since 6.0.0 Initial implementation of the method
15
+ *
16
  * @package AAM
17
+ * @version 6.6.0
18
  */
19
  class AAM_Service_Shortcode
20
  {
62
  *
63
  * @return void
64
  *
65
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/90
66
+ * @since 6.0.0 Initial implementation of the method
67
+ *
68
  * @access protected
69
+ * @version 6.6.0
70
  */
71
  protected function initializeHooks()
72
  {
76
 
77
  return $shortcode->process();
78
  });
79
+ add_shortcode('aam-login', function($args, $content) {
80
+ $shortcode = new AAM_Shortcode_Handler_LoginForm($args, $content);
81
+
82
+ return $shortcode->run();
83
+ });
84
  }
85
  }
86
 
application/Shortcode/Factory.php CHANGED
@@ -5,15 +5,16 @@
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
8
- *
9
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * Shortcode factory for the [aam] shortcode
14
  *
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Shortcode_Factory
19
  {
@@ -36,8 +37,11 @@ class AAM_Shortcode_Factory
36
  *
37
  * @return void
38
  *
 
 
 
39
  * @access public
40
- * @version 6.0.0
41
  */
42
  public function __construct($args, $content)
43
  {
@@ -47,6 +51,8 @@ class AAM_Shortcode_Factory
47
  $this->handler = new AAM_Shortcode_Handler_Content($args, $content);
48
  } elseif ($cnt === 'loginredirect') {
49
  $this->handler = new AAM_Shortcode_Handler_LoginRedirect($args, $content);
 
 
50
  } else {
51
  $this->handler = apply_filters(
52
  'aam_shortcode_filter', null, $cnt, $args, $content
5
  * LICENSE: This file is subject to the terms and conditions defined in *
6
  * file 'license.txt', which is part of this source code package. *
7
  * ======================================================================
 
 
8
  */
9
 
10
  /**
11
  * Shortcode factory for the [aam] shortcode
12
  *
13
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/90
14
+ * @since 6.0.0 Initial implementation of the class
15
+ *
16
  * @package AAM
17
+ * @version 6.6.0
18
  */
19
  class AAM_Shortcode_Factory
20
  {
37
  *
38
  * @return void
39
  *
40
+ * @since 6.6.0 https://github.com/aamplugin/advanced-access-manager/issues/90
41
+ * @since 6.0.0 Initial implementation of the method
42
+ *
43
  * @access public
44
+ * @version 6.6.0
45
  */
46
  public function __construct($args, $content)
47
  {
51
  $this->handler = new AAM_Shortcode_Handler_Content($args, $content);
52
  } elseif ($cnt === 'loginredirect') {
53
  $this->handler = new AAM_Shortcode_Handler_LoginRedirect($args, $content);
54
+ } elseif ($cnt === 'loginform') {
55
+ $this->handler = new AAM_Shortcode_Handler_LoginForm($args);
56
  } else {
57
  $this->handler = apply_filters(
58
  'aam_shortcode_filter', null, $cnt, $args, $content
application/Shortcode/Handler/LoginForm.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ * AAM shortcode strategy for login form
12
+ *
13
+ * @package AAM
14
+ * @version 6.6.0
15
+ */
16
+ class AAM_Shortcode_Handler_LoginForm
17
+ implements AAM_Core_Contract_ShortcodeInterface
18
+ {
19
+
20
+ /**
21
+ * Shortcode arguments
22
+ *
23
+ * @var array
24
+ *
25
+ * @access protected
26
+ * @version 6.6.0
27
+ */
28
+ protected $args;
29
+
30
+ /**
31
+ * Initialize shortcode decorator
32
+ *
33
+ * Expecting attributes in $args are:
34
+ * "class" => CSS class for login form
35
+ * "redirect" => Redirect to URL after successful login
36
+ *
37
+ * @param array $args
38
+ *
39
+ * @return void
40
+ *
41
+ * @access public
42
+ * @version 6.6.0
43
+ */
44
+ public function __construct($args, $content = null)
45
+ {
46
+ $this->args = array_merge(
47
+ array('class' => '', 'redirect' => ''),
48
+ $args
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Process the shortcode
54
+ *
55
+ * @return string
56
+ *
57
+ * @access public
58
+ * @version 6.6.0
59
+ */
60
+ public function run()
61
+ {
62
+ return AAM_Backend_View::loadPartial('login-form', array_merge(
63
+ $this->args,
64
+ array('id' => uniqid())
65
+ ));
66
+ }
67
+
68
+ }
media/js/aam.js CHANGED
@@ -1018,7 +1018,7 @@
1018
  try {
1019
  if ($.trim($('#user-expires').val())) {
1020
  $('#user-expiration-datapicker').data('DateTimePicker').defaultDate(
1021
- $('#user-expires').val()
1022
  );
1023
  } else {
1024
  var tomorrow = new Date();
1018
  try {
1019
  if ($.trim($('#user-expires').val())) {
1020
  $('#user-expiration-datapicker').data('DateTimePicker').defaultDate(
1021
+ new Date($('#user-expires').val())
1022
  );
1023
  } else {
1024
  var tomorrow = new Date();
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: vasyltech
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.7.0
5
  Requires PHP: 5.6.0
6
- Tested up to: 5.4.1
7
- Stable tag: 6.5.4
8
 
9
  All you need to manage access to WordPress websites on the frontend, backend and API levels for any role, user or visitors.
10
 
@@ -91,6 +91,16 @@ We take security and privacy very seriously, that is why there are several non-n
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
 
 
94
  = 6.5.4 =
95
  * Fixed Bug: Incorectly evaluated best candidate for the conditional statement [https://github.com/aamplugin/advanced-access-manager/issues/128](https://github.com/aamplugin/advanced-access-manager/issues/128)
96
 
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.7.0
5
  Requires PHP: 5.6.0
6
+ Tested up to: 5.4.2
7
+ Stable tag: 6.6.0
8
 
9
  All you need to manage access to WordPress websites on the frontend, backend and API levels for any role, user or visitors.
10
 
91
 
92
  == Changelog ==
93
 
94
+ = 6.6.0 =
95
+ * Fixed Bug: No ability to "allow" API Route [https://github.com/aamplugin/advanced-access-manager/issues/131](https://github.com/aamplugin/advanced-access-manager/issues/131)
96
+ * Fixed Bug: Passwordless login sets cookie that might logout issues [https://github.com/aamplugin/advanced-access-manager/issues/129](https://github.com/aamplugin/advanced-access-manager/issues/129)
97
+ * Fixed Bug: AAM does not retain selected time [https://github.com/aamplugin/advanced-access-manager/issues/133](https://github.com/aamplugin/advanced-access-manager/issues/133)
98
+ * Changed: Logout user automatically if JWT token is revoked [https://github.com/aamplugin/advanced-access-manager/issues/118](https://github.com/aamplugin/advanced-access-manager/issues/118)
99
+ * Changed: Enhance Backend Menu service [https://github.com/aamplugin/advanced-access-manager/issues/114](https://github.com/aamplugin/advanced-access-manager/issues/114)
100
+ * Added New: The ability to export/import access policies [https://github.com/aamplugin/advanced-access-manager/issues/130](https://github.com/aamplugin/advanced-access-manager/issues/130)
101
+ * Added New: Add `roles` claim to the issued JWT token [https://github.com/aamplugin/advanced-access-manager/issues/100](https://github.com/aamplugin/advanced-access-manager/issues/100)
102
+ * Added New: [aam-login] shortcode that renders AAM secure login form [https://github.com/aamplugin/advanced-access-manager/issues/90](https://github.com/aamplugin/advanced-access-manager/issues/90)
103
+
104
  = 6.5.4 =
105
  * Fixed Bug: Incorectly evaluated best candidate for the conditional statement [https://github.com/aamplugin/advanced-access-manager/issues/128](https://github.com/aamplugin/advanced-access-manager/issues/128)
106