Advanced Access Manager - Version 5.4

Version Description

  • Fixed bug with Api Access Control option that when disabled, still denies API Routes
  • Fixed bug when RESTful or XML-RPC disabled but endpoints still listed on API Routes
  • Fixed bug with Secure Login for themes that are not build with jQuery support
  • Fixed bug with posts not been filtered during search in few post types
  • Added ability to manage Admin Toolbar items
  • Added ability to manage premium licenses so now user can transfer license anytime
  • Moved security options (brute force lockout, login timeout etc) to stand-alone Security tab
  • Improved UI for the ACCESS EXPIRATION option on Posts & Terms tab
  • Improved UI for defining temporary user account timespan
  • Removed deprecated "Check Post Visibility" option
Download this release

Release Info

Developer vasyl_m
Plugin Icon 128x128 Advanced Access Manager
Version 5.4
Comparing to
See all releases

Code changes from version 5.3.5 to 5.4

Files changed (39) hide show
  1. Application/Api/Manager.php +17 -21
  2. Application/Backend/Feature/Main/Capability.php +1 -1
  3. Application/Backend/Feature/Main/Post.php +0 -4
  4. Application/Backend/Feature/Main/Route.php +24 -21
  5. Application/Backend/Feature/Main/Toolbar.php +169 -0
  6. Application/Backend/Feature/Settings/Content.php +0 -5
  7. Application/Backend/Feature/Settings/Core.php +3 -3
  8. Application/Backend/Feature/Settings/Security.php +74 -0
  9. Application/Backend/Feature/Subject/User.php +1 -1
  10. Application/Backend/Filter.php +0 -57
  11. Application/Backend/Manager.php +36 -0
  12. Application/Backend/View.php +2 -0
  13. Application/Backend/View/PostOptionList.php +0 -3
  14. Application/Backend/Widget/Login.php +1 -39
  15. Application/Backend/phtml/index.phtml +5 -25
  16. Application/Backend/phtml/main/menu.phtml +1 -1
  17. Application/Backend/phtml/main/toolbar.phtml +90 -0
  18. Application/Backend/phtml/partial/post-advanced-settings.phtml +2 -8
  19. Application/Backend/phtml/settings/security.phtml +21 -0
  20. Application/Backend/phtml/widget/login-backend.phtml +1 -19
  21. Application/Core/Compatibility.php +3 -1
  22. Application/Core/Gateway.php +1 -1
  23. Application/Core/Login.php +3 -3
  24. Application/Core/Object/Toolbar.php +116 -0
  25. Application/Extension/List.php +2 -2
  26. Application/Frontend/Authorization.php +3 -2
  27. Application/Frontend/Filter.php +6 -9
  28. Application/Frontend/Manager.php +5 -1
  29. Application/Shared/Manager.php +55 -22
  30. aam.php +1 -1
  31. media/css/aam.css +381 -0
  32. media/font/fontello.eot +0 -0
  33. media/font/fontello.svg +10 -0
  34. media/font/fontello.ttf +0 -0
  35. media/font/fontello.woff +0 -0
  36. media/font/fontello.woff2 +0 -0
  37. media/js/aam.js +257 -3
  38. media/js/vendor.js +9 -1
  39. readme.txt +42 -20
Application/Api/Manager.php CHANGED
@@ -57,30 +57,26 @@ class AAM_Api_Manager {
57
  * @access public
58
  */
59
  protected function __construct() {
60
- // REST API action authorization. Triggered before call is dispatched
61
- add_filter(
62
- 'rest_request_before_callbacks', array($this, 'beforeDispatch'), 10, 3
63
- );
64
-
65
- // Manage access to the RESTful endpoints
66
- add_filter('rest_pre_dispatch', array($this, 'authorizeRest'), 1, 3);
67
-
68
- // Check if user has ability to perform certain task based on provided
69
- // capability and meta data
70
  if (AAM_Core_Config::get('core.settings.apiAccessControl', true)) {
 
71
  add_filter(
72
- 'user_has_cap',
73
- array(AAM_Shared_Manager::getInstance(), 'userHasCap'),
74
- 999,
75
- 3
76
  );
77
- }
78
-
79
- // Register any additional endpoints with ConfigPress
80
- $additional = AAM_Core_Config::get('rest.manage.endpoint');
81
-
82
- if (!empty($additional) && is_array($additional)) {
83
- $this->resources = array_merge_recursive($this->resources, $additional);
 
 
 
 
 
 
 
 
84
  }
85
  }
86
 
57
  * @access public
58
  */
59
  protected function __construct() {
 
 
 
 
 
 
 
 
 
 
60
  if (AAM_Core_Config::get('core.settings.apiAccessControl', true)) {
61
+ // REST API action authorization. Triggered before call is dispatched
62
  add_filter(
63
+ 'rest_request_before_callbacks', array($this, 'beforeDispatch'), 10, 3
 
 
 
64
  );
65
+
66
+ // Manage access to the RESTful endpoints
67
+ add_filter('rest_pre_dispatch', array($this, 'authorizeRest'), 1, 3);
68
+
69
+ // Check if user has ability to perform certain task based on provided
70
+ // capability and meta data
71
+ $shared = AAM_Shared_Manager::getInstance();
72
+ add_filter('user_has_cap', array($shared, 'userHasCap'), 999, 3);
73
+
74
+ // Register any additional endpoints with ConfigPress
75
+ $additional = AAM_Core_Config::get('rest.manage.endpoint');
76
+
77
+ if (!empty($additional) && is_array($additional)) {
78
+ $this->resources = array_merge_recursive($this->resources, $additional);
79
+ }
80
  }
81
  }
82
 
Application/Backend/Feature/Main/Capability.php CHANGED
@@ -51,7 +51,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
51
  'aam_manage_posts', 'aam_manage_access_denied_redirect', 'aam_create_roles',
52
  'aam_manage_login_redirect', 'aam_manage_logout_redirect', 'aam_manager',
53
  'aam_manage_settings', 'aam_manage_extensions', 'aam_show_notifications',
54
- 'aam_manage_404_redirect', 'aam_manage_ip_check',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_list_roles',
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
  'aam_manage_configpress', 'aam_manage_api_routes'
51
  'aam_manage_posts', 'aam_manage_access_denied_redirect', 'aam_create_roles',
52
  'aam_manage_login_redirect', 'aam_manage_logout_redirect', 'aam_manager',
53
  'aam_manage_settings', 'aam_manage_extensions', 'aam_show_notifications',
54
+ 'aam_manage_404_redirect', 'aam_manage_ip_check', 'aam_manage_toolbar',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_list_roles',
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
  'aam_manage_configpress', 'aam_manage_api_routes'
Application/Backend/Feature/Main/Post.php CHANGED
@@ -451,10 +451,6 @@ class AAM_Backend_Feature_Main_Post extends AAM_Backend_Feature_Abstract {
451
  $param = AAM_Core_Request::post('param');
452
  $value = AAM_Core_Request::post('value');
453
 
454
- if (strpos($param, '.expire_datetime') !== false) {
455
- $value = date('Y-m-d H:i:s', strtotime($value));
456
- }
457
-
458
  //clear cache
459
  AAM_Core_API::clearCache();
460
 
451
  $param = AAM_Core_Request::post('param');
452
  $value = AAM_Core_Request::post('value');
453
 
 
 
 
 
454
  //clear cache
455
  AAM_Core_API::clearCache();
456
 
Application/Backend/Feature/Main/Route.php CHANGED
@@ -56,35 +56,38 @@ class AAM_Backend_Feature_Main_Route extends AAM_Backend_Feature_Abstract {
56
  protected function retrieveAllRoutes() {
57
  $response = array();
58
  $object = AAM_Backend_Subject::getInstance()->getObject('route');
59
- $routes = rest_get_server()->get_routes();
60
 
61
  //build all RESTful routes
62
- foreach ($routes as $route => $handlers) {
63
- $methods = array();
64
- foreach($handlers as $handler) {
65
- $methods = array_merge($methods, array_keys($handler['methods']));
 
 
 
 
 
 
 
 
 
 
 
66
  }
 
67
 
68
- foreach(array_unique($methods) as $method) {
 
 
69
  $response[] = array(
70
- 'restful',
71
- $method,
72
  htmlspecialchars($route),
73
- $object->has('restful', $route, $method) ? 'checked' : 'unchecked'
74
  );
75
  }
76
  }
77
 
78
- // Build XML RPC routes
79
- foreach(array_keys(AAM_Core_API::getXMLRPCServer()->methods) as $route) {
80
- $response[] = array(
81
- 'xmlrpc',
82
- 'POST',
83
- htmlspecialchars($route),
84
- $object->has('xmlrpc', $route) ? 'checked' : 'unchecked'
85
- );
86
- }
87
-
88
  return $response;
89
  }
90
 
@@ -114,7 +117,7 @@ class AAM_Backend_Feature_Main_Route extends AAM_Backend_Feature_Abstract {
114
  AAM_Backend_Feature::registerFeature((object) array(
115
  'uid' => 'route',
116
  'position' => 50,
117
- 'title' => __('API Routes', AAM_KEY) . ' <span class="badge">NEW</span>',
118
  'capability' => 'aam_manage_api_routes',
119
  'type' => 'main',
120
  'subjects' => array(
@@ -123,7 +126,7 @@ class AAM_Backend_Feature_Main_Route extends AAM_Backend_Feature_Abstract {
123
  AAM_Core_Subject_Visitor::UID,
124
  AAM_Core_Subject_Default::UID
125
  ),
126
- 'option' => 'core.settings.restful',
127
  'view' => __CLASS__
128
  ));
129
  }
56
  protected function retrieveAllRoutes() {
57
  $response = array();
58
  $object = AAM_Backend_Subject::getInstance()->getObject('route');
 
59
 
60
  //build all RESTful routes
61
+ if (AAM::api()->getConfig('core.settings.restful', true)) {
62
+ foreach (rest_get_server()->get_routes() as $route => $handlers) {
63
+ $methods = array();
64
+ foreach($handlers as $handler) {
65
+ $methods = array_merge($methods, array_keys($handler['methods']));
66
+ }
67
+
68
+ foreach(array_unique($methods) as $method) {
69
+ $response[] = array(
70
+ 'restful',
71
+ $method,
72
+ htmlspecialchars($route),
73
+ $object->has('restful', $route, $method) ? 'checked' : 'unchecked'
74
+ );
75
+ }
76
  }
77
+ }
78
 
79
+ // Build XML RPC routes
80
+ if (AAM::api()->getConfig('core.settings.xmlrpc', true)) {
81
+ foreach(array_keys(AAM_Core_API::getXMLRPCServer()->methods) as $route) {
82
  $response[] = array(
83
+ 'xmlrpc',
84
+ 'POST',
85
  htmlspecialchars($route),
86
+ $object->has('xmlrpc', $route) ? 'checked' : 'unchecked'
87
  );
88
  }
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
91
  return $response;
92
  }
93
 
117
  AAM_Backend_Feature::registerFeature((object) array(
118
  'uid' => 'route',
119
  'position' => 50,
120
+ 'title' => __('API Routes', AAM_KEY),
121
  'capability' => 'aam_manage_api_routes',
122
  'type' => 'main',
123
  'subjects' => array(
126
  AAM_Core_Subject_Visitor::UID,
127
  AAM_Core_Subject_Default::UID
128
  ),
129
+ 'option' => 'core.settings.apiAccessControl',
130
  'view' => __CLASS__
131
  ));
132
  }
Application/Backend/Feature/Main/Toolbar.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Backend menu manager
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Backend_Feature_Main_Toolbar extends AAM_Backend_Feature_Abstract {
17
+
18
+ /**
19
+ * Undocumented function
20
+ *
21
+ * @return void
22
+ */
23
+ public function save() {
24
+ $items = AAM_Core_Request::post('items', array());
25
+ $status = AAM_Core_Request::post('status');
26
+
27
+ $object = AAM_Backend_Subject::getInstance()->getObject('toolbar');
28
+
29
+ foreach($items as $item) {
30
+ $object->updateOptionItem($item, $status);
31
+ }
32
+
33
+ $object->save();
34
+
35
+ return json_encode(array('status' => 'success'));
36
+ }
37
+
38
+ /**
39
+ * Get subject's menu
40
+ *
41
+ * Based on the list of capabilities that current subject has, prepare
42
+ * complete menu list and return it.
43
+ *
44
+ * @return array
45
+ *
46
+ * @access public
47
+ * @global array $menu
48
+ */
49
+ public function getToolbar() {
50
+ return AAM_Core_API::getOption('aam_toolbar_cache', array());
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param type $branch
56
+ * @return type
57
+ */
58
+ public function getAllChildren($branch) {
59
+ $children = array();
60
+
61
+ foreach($branch->children as $child) {
62
+ if (empty($child->type) || !in_array($child->type, array('container', 'group'))) {
63
+ $children[] = $child;
64
+ }
65
+ if(!empty($child->children)) {
66
+ $children = array_merge($children, $this->getAllChildren($child));
67
+ }
68
+ }
69
+
70
+ return $children;
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @param type $node
76
+ * @return type
77
+ */
78
+ public function normalizeTitle($node) {
79
+ return ucwords(
80
+ trim(
81
+ preg_replace(
82
+ '/[\d]/',
83
+ '',
84
+ strip_tags(!empty($node->title) ? $node->title : $node->id)
85
+ )
86
+ )
87
+ );
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @return type
93
+ */
94
+ public function refreshList() {
95
+ // reset cache
96
+ AAM_Core_API::deleteOption('aam_toolbar_cache');
97
+
98
+ //grab toolbar itesm
99
+ AAM_Core_API::cURL($this->addHttpPasswd(
100
+ add_query_arg('init', 'toolbar', admin_url('index.php')))
101
+ );
102
+
103
+ return json_encode(array('status' => 'success'));
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @param type $url
109
+ * @return type
110
+ */
111
+ protected function addHttpPasswd($url) {
112
+ $htpasswd = AAM_Core_Config::get('feature.toolbar.htpasswd');
113
+
114
+ if (!empty($htpasswd['user']) && !empty($htpasswd['pass'])) {
115
+ $url = preg_replace(
116
+ '/^(http[s]?:\/\/)/', "$1{$htpasswd['user']}:{$htpasswd['pass']}@", $url
117
+ );
118
+ }
119
+
120
+ return $url;
121
+ }
122
+
123
+ /**
124
+ * @inheritdoc
125
+ */
126
+ public static function getTemplate() {
127
+ return 'main/toolbar.phtml';
128
+ }
129
+
130
+ /**
131
+ * Check inheritance status
132
+ *
133
+ * Check if menu settings are overwritten
134
+ *
135
+ * @return boolean
136
+ *
137
+ * @access protected
138
+ */
139
+ protected function isOverwritten() {
140
+ $object = AAM_Backend_Subject::getInstance()->getObject('toolbar');
141
+
142
+ return $object->isOverwritten();
143
+ }
144
+
145
+ /**
146
+ * Register Menu feature
147
+ *
148
+ * @return void
149
+ *
150
+ * @access public
151
+ */
152
+ public static function register() {
153
+ AAM_Backend_Feature::registerFeature((object) array(
154
+ 'uid' => 'toolbar',
155
+ 'position' => 6,
156
+ 'title' => __('Admin Toolbar', AAM_KEY),
157
+ 'capability' => 'aam_manage_toolbar',
158
+ 'type' => 'main',
159
+ 'subjects' => array(
160
+ AAM_Core_Subject_Role::UID,
161
+ AAM_Core_Subject_User::UID,
162
+ AAM_Core_Subject_Default::UID
163
+ ),
164
+ 'option' => 'core.settings.backendAccessControl,core.settings.frontendAccessControl',
165
+ 'view' => __CLASS__
166
+ ));
167
+ }
168
+
169
+ }
Application/Backend/Feature/Settings/Content.php CHANGED
@@ -33,11 +33,6 @@ class AAM_Backend_Feature_Settings_Content extends AAM_Backend_Feature_Abstract
33
  'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Allow AAM to manage a physically access to all media files located in the defined by the system [uploads] folder. [Note!] This feature requires additional steps as described in %sthis article%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-to-manage-wordpress-media-access" target="_blank">', '</a>'),
34
  'value' => AAM_Core_Config::get('core.settings.mediaAccessControl', false)
35
  ),
36
- 'core.settings.checkPostVisibility' => array(
37
- 'title' => __('Check Post Visibility', AAM_KEY),
38
- 'descr' => __('For performance reasons, keep this option disabled if do not use LIST or LIST TO OTHERS access options on Posts & Terms tab. When it is checked, AAM will filter list of posts that are hidden for a user on frontend, backend and API calls.', AAM_KEY),
39
- 'value' => AAM_Core_Config::get('core.settings.checkPostVisibility', true)
40
- ),
41
  'core.settings.manageHiddenPostTypes' => array(
42
  'title' => __('Manage Hidden Post Types', AAM_KEY),
43
  'descr' => __('By default AAM allows you to manage access only to public post types on Posts & Terms tab. By enabling this feature, you also will be able to manage access to hidden post types like revisions, navigation menus or any other custom post types that are not registered as public.', AAM_KEY),
33
  'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Allow AAM to manage a physically access to all media files located in the defined by the system [uploads] folder. [Note!] This feature requires additional steps as described in %sthis article%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-to-manage-wordpress-media-access" target="_blank">', '</a>'),
34
  'value' => AAM_Core_Config::get('core.settings.mediaAccessControl', false)
35
  ),
 
 
 
 
 
36
  'core.settings.manageHiddenPostTypes' => array(
37
  'title' => __('Manage Hidden Post Types', AAM_KEY),
38
  'descr' => __('By default AAM allows you to manage access only to public post types on Posts & Terms tab. By enabling this feature, you also will be able to manage access to hidden post types like revisions, navigation menus or any other custom post types that are not registered as public.', AAM_KEY),
Application/Backend/Feature/Settings/Core.php CHANGED
@@ -35,17 +35,17 @@ class AAM_Backend_Feature_Settings_Core extends AAM_Backend_Feature_Abstract {
35
  ),
36
  'core.settings.backendAccessControl' => array(
37
  'title' => __('Backend Access Control', AAM_KEY),
38
- 'descr' => __('Allow AAM to manage access to the backend. Note! Keep this option disabled if there is no needs to restrict backend features for other users.', AAM_KEY),
39
  'value' => AAM_Core_Config::get('core.settings.backendAccessControl', true)
40
  ),
41
  'core.settings.frontendAccessControl' => array(
42
  'title' => __('Frontend Access Control', AAM_KEY),
43
- 'descr' => __('Allow AAM to manage access to the frontend. Note! Keep this option disabled if there is no needs to restrict frontend resources for users and visitors.', AAM_KEY),
44
  'value' => AAM_Core_Config::get('core.settings.frontendAccessControl', true)
45
  ),
46
  'core.settings.apiAccessControl' => array(
47
  'title' => __('API Access Control', AAM_KEY),
48
- 'descr' => __('Allow AAM to manage access to the website resources that are invoked with WordPress core APIs (currently only for RESTful API). Note! Keep this option disabled if there is no needs to restrict API access.', AAM_KEY),
49
  'value' => AAM_Core_Config::get('core.settings.apiAccessControl', true)
50
  ),
51
  'ui.settings.renderAccessMetabox' => array(
35
  ),
36
  'core.settings.backendAccessControl' => array(
37
  'title' => __('Backend Access Control', AAM_KEY),
38
+ 'descr' => __('Allow AAM to manage access to the backend. Keep this option disabled if there is no needs to restrict backend features for other users.', AAM_KEY),
39
  'value' => AAM_Core_Config::get('core.settings.backendAccessControl', true)
40
  ),
41
  'core.settings.frontendAccessControl' => array(
42
  'title' => __('Frontend Access Control', AAM_KEY),
43
+ 'descr' => __('Allow AAM to manage access to the frontend. Keep this option disabled if there is no needs to restrict frontend resources for users and visitors.', AAM_KEY),
44
  'value' => AAM_Core_Config::get('core.settings.frontendAccessControl', true)
45
  ),
46
  'core.settings.apiAccessControl' => array(
47
  'title' => __('API Access Control', AAM_KEY),
48
+ 'descr' => __('Allow AAM to manage access to the website resources that are invoked with WordPress core APIs. Keep this option disabled if there is no needs to restrict API access.', AAM_KEY),
49
  'value' => AAM_Core_Config::get('core.settings.apiAccessControl', true)
50
  ),
51
  'ui.settings.renderAccessMetabox' => array(
Application/Backend/Feature/Settings/Security.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Backend security settings
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Backend_Feature_Settings_Security extends AAM_Backend_Feature_Abstract {
17
+
18
+ /**
19
+ * @inheritdoc
20
+ */
21
+ public static function getTemplate() {
22
+ return 'settings/security.phtml';
23
+ }
24
+
25
+ /**
26
+ *
27
+ * @return type
28
+ */
29
+ protected function getList() {
30
+ $settings = array(
31
+ 'core.settings.loginTimeout' => array(
32
+ 'title' => __('Login Timeout', AAM_KEY),
33
+ 'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Delay the login process for 1 second (the value is configurable) to significantly reduce the chance for brute force or dictionary attack. For more information about this option please refer to %sHow does AAM Secure Login works%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'),
34
+ 'value' => AAM_Core_Config::get('core.settings.loginTimeout', false)
35
+ ),
36
+ 'core.settings.loginTimeout' => array(
37
+ 'title' => __('Login Timeout', AAM_KEY),
38
+ 'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Delay the login process for 1 second (the value is configurable) to significantly reduce the chance for brute force or dictionary attack. For more information about this option please refer to %sHow does AAM Secure Login works%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'),
39
+ 'value' => AAM_Core_Config::get('core.settings.loginTimeout', false)
40
+ ),
41
+ 'core.settings.singleSession' => array(
42
+ 'title' => __('One Session Per User', AAM_KEY),
43
+ 'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Automatically destroy all other sessions for a user if he/she tries to login from different location. For more information about this option please refer to %sHow does AAM Secure Login works%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'),
44
+ 'value' => AAM_Core_Config::get('core.settings.singleSession', false)
45
+ ),
46
+ 'core.settings.bruteForceLockout' => array(
47
+ 'title' => __('Brute Force Lockout', AAM_KEY),
48
+ 'descr' => sprintf(AAM_Backend_View_Helper::preparePhrase('Automatically reject login attempts if number of unsuccessful login attempts is more than 20 over the period of 2 minutes (both values are configurable). For more information about this option please refer to %sHow does AAM Secure Login works%s.', 'strong', 'strong'), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'),
49
+ 'value' => AAM_Core_Config::get('core.settings.bruteForceLockout', false)
50
+ ),
51
+ );
52
+
53
+ return apply_filters('aam-settings-filter', $settings, 'security');
54
+ }
55
+
56
+ /**
57
+ * Register Contact/Hire feature
58
+ *
59
+ * @return void
60
+ *
61
+ * @access public
62
+ */
63
+ public static function register() {
64
+ AAM_Backend_Feature::registerFeature((object) array(
65
+ 'uid' => 'settings-security',
66
+ 'position' => 6,
67
+ 'title' => __('Security Settings', AAM_KEY),
68
+ 'capability' => 'aam_manage_settings',
69
+ 'type' => 'settings',
70
+ 'view' => __CLASS__
71
+ ));
72
+ }
73
+
74
+ }
Application/Backend/Feature/Subject/User.php CHANGED
@@ -234,7 +234,7 @@ class AAM_Backend_Feature_Subject_User {
234
  update_user_meta(
235
  $user,
236
  'aam_user_expiration',
237
- date('Y-m-d H:i:s', strtotime($expires)) . "|" . ($action ? $action : 'delete') . '|' . $role
238
  );
239
  } else {
240
  delete_user_meta($user, 'aam_user_expiration');
234
  update_user_meta(
235
  $user,
236
  'aam_user_expiration',
237
+ $expires . "|" . ($action ? $action : 'delete') . '|' . $role
238
  );
239
  } else {
240
  delete_user_meta($user, 'aam_user_expiration');
Application/Backend/Filter.php CHANGED
@@ -44,9 +44,6 @@ class AAM_Backend_Filter {
44
  add_action('network_admin_notices', array($this, 'adminNotices'), -1);
45
  add_action('user_admin_notices', array($this, 'adminNotices'), -1);
46
 
47
- //admin bar
48
- add_action('wp_before_admin_bar_render', array($this, 'filterAdminBar'), 999);
49
-
50
  //post restrictions
51
  add_filter('page_row_actions', array($this, 'postRowActions'), 10, 2);
52
  add_filter('post_row_actions', array($this, 'postRowActions'), 10, 2);
@@ -137,60 +134,6 @@ class AAM_Backend_Filter {
137
  }
138
  }
139
 
140
- /**
141
- * Filter top admin bar
142
- *
143
- * The filter will be performed based on the Backend Menu access settings
144
- *
145
- * @return void
146
- *
147
- * @access public
148
- * @global WP_Admin_Bar $wp_admin_bar
149
- */
150
- public function filterAdminBar() {
151
- global $wp_admin_bar;
152
-
153
- $menu = AAM::getUser()->getObject('menu');
154
- foreach($wp_admin_bar->get_nodes() as $id => $node) {
155
- if (!empty($node->href)) {
156
- $suffix = str_replace(admin_url(), '', $node->href);
157
- if ($menu->has($suffix, true)) {
158
- if (empty($node->parent) && $this->hasChildren($id)) { //root level
159
- $node->href = '#';
160
- $wp_admin_bar->add_node($node);
161
- } else {
162
- $wp_admin_bar->remove_menu($id);
163
- }
164
- }
165
- }
166
- }
167
- }
168
-
169
- /**
170
- * Check if specified top bar item has children
171
- *
172
- * @param string $id
173
- *
174
- * @return boolean
175
- *
176
- * @access protected
177
- * @global WP_Admin_Bar $wp_admin_bar
178
- */
179
- protected function hasChildren($id) {
180
- global $wp_admin_bar;
181
-
182
- $has = false;
183
-
184
- foreach($wp_admin_bar->get_nodes() as $node) {
185
- if ($node->parent == $id) {
186
- $has = true;
187
- break;
188
- }
189
- }
190
-
191
- return $has;
192
- }
193
-
194
  /**
195
  * Post Quick Menu Actions Filtering
196
  *
44
  add_action('network_admin_notices', array($this, 'adminNotices'), -1);
45
  add_action('user_admin_notices', array($this, 'adminNotices'), -1);
46
 
 
 
 
47
  //post restrictions
48
  add_filter('page_row_actions', array($this, 'postRowActions'), 10, 2);
49
  add_filter('post_row_actions', array($this, 'postRowActions'), 10, 2);
134
  }
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  /**
138
  * Post Quick Menu Actions Filtering
139
  *
Application/Backend/Manager.php CHANGED
@@ -107,6 +107,11 @@ class AAM_Backend_Manager {
107
  //control admin area
108
  add_action('admin_init', array($this, 'adminInit'));
109
 
 
 
 
 
 
110
  //register login widget
111
  if (AAM_Core_Config::get('core.settings.secureLogin', true)) {
112
  add_action('widgets_init', array($this, 'registerLoginWidget'));
@@ -384,6 +389,37 @@ class AAM_Backend_Manager {
384
  }
385
  }
386
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  /**
388
  *
389
  * @global type $post
107
  //control admin area
108
  add_action('admin_init', array($this, 'adminInit'));
109
 
110
+ //admin toolbar
111
+ if (filter_input(INPUT_GET, 'init') == 'toolbar') {
112
+ add_action('wp_after_admin_bar_render', array($this, 'adminBar'));
113
+ }
114
+
115
  //register login widget
116
  if (AAM_Core_Config::get('core.settings.secureLogin', true)) {
117
  add_action('widgets_init', array($this, 'registerLoginWidget'));
389
  }
390
  }
391
 
392
+ /**
393
+ *
394
+ * @global type $wp_admin_bar
395
+ */
396
+ public function adminBar() {
397
+ global $wp_admin_bar;
398
+
399
+ $reflection = new ReflectionClass(get_class($wp_admin_bar));
400
+
401
+ $prop = $reflection->getProperty('nodes');
402
+ $prop->setAccessible(true);
403
+
404
+ $nodes = $prop->getValue($wp_admin_bar);
405
+
406
+ if (isset($nodes['root'])) {
407
+ $cache = array();
408
+ foreach($nodes['root']->children as $node) {
409
+ $cache = array_merge($cache, $node->children);
410
+ }
411
+
412
+ // do some cleanup
413
+ foreach($cache as $i => $node) {
414
+ if ($node->id == 'menu-toggle') {
415
+ unset($cache[$i]);
416
+ }
417
+ }
418
+
419
+ AAM_Core_API::updateOption('aam_toolbar_cache', array_values($cache));
420
+ }
421
+ }
422
+
423
  /**
424
  *
425
  * @global type $post
Application/Backend/View.php CHANGED
@@ -34,6 +34,7 @@ class AAM_Backend_View {
34
  protected function __construct() {
35
  //register default features
36
  AAM_Backend_Feature_Main_Menu::register();
 
37
  AAM_Backend_Feature_Main_Metabox::register();
38
  AAM_Backend_Feature_Main_Capability::register();
39
  AAM_Backend_Feature_Main_Route::register();
@@ -45,6 +46,7 @@ class AAM_Backend_View {
45
 
46
  AAM_Backend_Feature_Settings_Core::register();
47
  AAM_Backend_Feature_Settings_Content::register();
 
48
  AAM_Backend_Feature_Settings_Tools::register();
49
  AAM_Backend_Feature_Settings_ConfigPress::register();
50
 
34
  protected function __construct() {
35
  //register default features
36
  AAM_Backend_Feature_Main_Menu::register();
37
+ AAM_Backend_Feature_Main_Toolbar::register();
38
  AAM_Backend_Feature_Main_Metabox::register();
39
  AAM_Backend_Feature_Main_Capability::register();
40
  AAM_Backend_Feature_Main_Route::register();
46
 
47
  AAM_Backend_Feature_Settings_Core::register();
48
  AAM_Backend_Feature_Settings_Content::register();
49
+ AAM_Backend_Feature_Settings_Security::register();
50
  AAM_Backend_Feature_Settings_Tools::register();
51
  AAM_Backend_Feature_Settings_ConfigPress::register();
52
 
Application/Backend/View/PostOptionList.php CHANGED
@@ -25,7 +25,6 @@ class AAM_Backend_View_PostOptionList {
25
  'list' => array(
26
  'title' => __('List', AAM_KEY),
27
  'descr' => __('Hide %s however still allow access with direct URL.', AAM_KEY) . sprintf(__(' %sSee in action.%s', AAM_KEY), "<a href='https://youtu.be/2jiu_CL6JJg' target='_blank'>", '</a>'),
28
- 'config' => 'core.settings.checkPostVisibility'
29
  ),
30
  'read' => array(
31
  'title' => __('Read', AAM_KEY),
@@ -91,7 +90,6 @@ class AAM_Backend_View_PostOptionList {
91
  'title' => __('List', AAM_KEY),
92
  'exclude' => array(AAM_Core_Subject_Visitor::UID),
93
  'descr' => __('Hide %s however still allow access with direct URL.', AAM_KEY),
94
- 'config' => 'core.settings.checkPostVisibility'
95
  ),
96
  'edit' => array(
97
  'title' => __('Edit', AAM_KEY),
@@ -113,7 +111,6 @@ class AAM_Backend_View_PostOptionList {
113
  'list' => array(
114
  'title' => __('List', AAM_KEY),
115
  'descr' => __('Hide %s however still allow access to retrieve %s.', AAM_KEY),
116
- 'config' => 'core.settings.checkPostVisibility'
117
  ),
118
  'read' => array(
119
  'title' => __('Read', AAM_KEY),
25
  'list' => array(
26
  'title' => __('List', AAM_KEY),
27
  'descr' => __('Hide %s however still allow access with direct URL.', AAM_KEY) . sprintf(__(' %sSee in action.%s', AAM_KEY), "<a href='https://youtu.be/2jiu_CL6JJg' target='_blank'>", '</a>'),
 
28
  ),
29
  'read' => array(
30
  'title' => __('Read', AAM_KEY),
90
  'title' => __('List', AAM_KEY),
91
  'exclude' => array(AAM_Core_Subject_Visitor::UID),
92
  'descr' => __('Hide %s however still allow access with direct URL.', AAM_KEY),
 
93
  ),
94
  'edit' => array(
95
  'title' => __('Edit', AAM_KEY),
111
  'list' => array(
112
  'title' => __('List', AAM_KEY),
113
  'descr' => __('Hide %s however still allow access to retrieve %s.', AAM_KEY),
 
114
  ),
115
  'read' => array(
116
  'title' => __('Read', AAM_KEY),
Application/Backend/Widget/Login.php CHANGED
@@ -48,51 +48,13 @@ class AAM_Backend_Widget_Login extends WP_Widget {
48
  require(dirname(__FILE__) . '/../phtml/widget/login-backend.phtml');
49
  }
50
 
51
- /**
52
- * Update widget
53
- *
54
- * @param array $new
55
- * @param array $old
56
- *
57
- * @return array
58
- *
59
- * @access public
60
- */
61
- public function update($new, $old) {
62
- $nlt = (isset($new['login-timeout']) ? $new['login-timeout'] : null);
63
- $olt = (isset($old['login-timeout']) ? $old['login-timeout'] : null);
64
-
65
- if ($nlt != $olt) {
66
- AAM_Core_Config::set('login-timeout', $nlt);
67
- }
68
-
69
- $nbl = (isset($new['brute-force-lockout']) ? $new['brute-force-lockout'] : null);
70
- $obl = (isset($old['brute-force-lockout']) ? $old['brute-force-lockout'] : null);
71
-
72
- if ($nbl != $obl) {
73
- AAM_Core_Config::set('brute-force-lockout', $nbl);
74
- }
75
-
76
- $nss = (isset($new['single-session']) ? $new['single-session'] : null);
77
- $oss = (isset($old['single-session']) ? $old['single-session'] : null);
78
-
79
- if ($nss != $oss) {
80
- AAM_Core_Config::set('single-session', $nss);
81
- }
82
-
83
- return parent::update($new, $old);
84
- }
85
-
86
  /**
87
  *
88
  * @param type $instance
89
  * @return type
90
  */
91
  protected function normalize($instance) {
92
- $instance['login-title'] = AAM_Core_Config::get('login-title');
93
- $instance['login-ip-track'] = AAM_Core_Config::get('login-ip-track');
94
- $instance['brute-force-lockout'] = AAM_Core_Config::get('brute-force-lockout');
95
- $instance['single-session'] = AAM_Core_Config::get('single-session');
96
 
97
  if (empty($instance['login-title'])) {
98
  $instance['login-title'] = __('Login', AAM_KEY);
48
  require(dirname(__FILE__) . '/../phtml/widget/login-backend.phtml');
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  *
53
  * @param type $instance
54
  * @return type
55
  */
56
  protected function normalize($instance) {
57
+ $instance['login-title'] = AAM_Core_Config::get('login-title');
 
 
 
58
 
59
  if (empty($instance['login-title'])) {
60
  $instance['login-title'] = __('Login', AAM_KEY);
Application/Backend/phtml/index.phtml CHANGED
@@ -137,7 +137,7 @@
137
  </td>
138
  <td>
139
  <div class="aam-row-actions">
140
- <a href="#transfer-license-modal" data-toggle="modal" class="aam-row-action"><i class="icon-exchange text-warning" data-toggle="tooltip" title="<?php echo __('Transfer License', AAM_KEY); ?>"></i></a>
141
  <?php if (!empty($license['expires'])) { ?>
142
  <a href="https://aamplugin.com/upgrade/<?php echo $license['license']; ?>" data-toggle="tooltip" title="<?php echo __('Upgrade License', AAM_KEY); ?>" class="aam-row-action" target="_blank"><i class="icon-angle-circled-up text-success"></i></a>
143
  <?php } ?>
@@ -151,27 +151,6 @@
151
  </div>
152
  </div>
153
  </div>
154
-
155
- <div class="modal fade" id="transfer-license-modal" tabindex="-1" role="dialog">
156
- <div class="modal-dialog modal-sm" role="document">
157
- <div class="modal-content">
158
- <div class="modal-header">
159
- <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
160
- <h4 class="modal-title"><?php echo __('Transfer license', AAM_KEY); ?></h4>
161
- </div>
162
- <div class="modal-body">
163
- <div class="form-group">
164
- <p class="aam-info">
165
- <?php echo AAM_Backend_View_Helper::preparePhrase('In order to transfer the license to a different domain, please contact us via email [support@aamplugin.com] with a reason for a transfer.', 'b'); ?>
166
- </p>
167
- </div>
168
- </div>
169
- <div class="modal-footer">
170
- <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
171
- </div>
172
- </div>
173
- </div>
174
- </div>
175
  <?php } ?>
176
 
177
  <div class="metabox-holder extensions-metabox" style="display:none;">
@@ -328,16 +307,17 @@
328
  </table>
329
 
330
  <div class="modal fade" id="edit-user-expiration-modal" tabindex="-1" role="dialog">
331
- <div class="modal-dialog modal-sm" role="document">
332
  <div class="modal-content">
333
  <div class="modal-header">
334
  <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
335
  <h4 class="modal-title"><?php echo __('Manage User Expiration', AAM_KEY); ?></h4>
336
  </div>
337
  <div class="modal-body">
 
338
  <div class="form-group">
339
- <label for="user-expires"><?php echo __('Expires', AAM_KEY); ?> <a href="https://aamplugin.com/help/how-to-create-temporary-wordpress-user-account" target="_blank" data-toggle="tooltip" title="For how long the user can stay active. Click to learn more."><i class="icon-help-circled"></i></a></label>
340
- <input type="text" class="form-control" id="user-expires" placeholder="<?php echo __('Enter Expiration', AAM_KEY); ?>" />
341
  </div>
342
  <div class="form-group">
343
  <label><?php echo __('Action After Expiration', AAM_KEY); ?> </label>
137
  </td>
138
  <td>
139
  <div class="aam-row-actions">
140
+ <a href="https://aamplugin.com/license/<?php echo $license['license']; ?>" class="aam-row-action"><i class="icon-cog text-success" data-toggle="tooltip" title="<?php echo __('Manage License', AAM_KEY); ?>"></i></a>
141
  <?php if (!empty($license['expires'])) { ?>
142
  <a href="https://aamplugin.com/upgrade/<?php echo $license['license']; ?>" data-toggle="tooltip" title="<?php echo __('Upgrade License', AAM_KEY); ?>" class="aam-row-action" target="_blank"><i class="icon-angle-circled-up text-success"></i></a>
143
  <?php } ?>
151
  </div>
152
  </div>
153
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  <?php } ?>
155
 
156
  <div class="metabox-holder extensions-metabox" style="display:none;">
307
  </table>
308
 
309
  <div class="modal fade" id="edit-user-expiration-modal" tabindex="-1" role="dialog">
310
+ <div class="modal-dialog" role="document">
311
  <div class="modal-content">
312
  <div class="modal-header">
313
  <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
314
  <h4 class="modal-title"><?php echo __('Manage User Expiration', AAM_KEY); ?></h4>
315
  </div>
316
  <div class="modal-body">
317
+ <p class="aam-info">To learn more about setting up temporary user accounts, please refer to <a href="https://aamplugin.com/help/how-to-create-temporary-wordpress-user-account" target="_blank">How to create temporary WordPress user account</a> article.</p>
318
  <div class="form-group">
319
+ <div id="user-expiration-datapicker"></div>
320
+ <input type="hidden" id="user-expires" />
321
  </div>
322
  <div class="form-group">
323
  <label><?php echo __('Action After Expiration', AAM_KEY); ?> </label>
Application/Backend/phtml/main/menu.phtml CHANGED
@@ -42,7 +42,7 @@
42
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
43
  <div class="panel-body">
44
  <?php if (!empty($menu['submenu'])) { ?>
45
- <div class="row">
46
  <?php echo ($object->has($menu['id']) ? '<div class="aam-lock"></div>' : ''); ?>
47
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
48
  <?php if ($submenu['id'] == 'index.php') { ?>
42
  <div id="menu-<?php echo $i; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="menu-<?php echo $i; ?>-heading">
43
  <div class="panel-body">
44
  <?php if (!empty($menu['submenu'])) { ?>
45
+ <div class="row aam-inner-tab">
46
  <?php echo ($object->has($menu['id']) ? '<div class="aam-lock"></div>' : ''); ?>
47
  <?php foreach ($menu['submenu'] as $j => $submenu) { ?>
48
  <?php if ($submenu['id'] == 'index.php') { ?>
Application/Backend/phtml/main/toolbar.phtml ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (defined('AAM_KEY')) { ?>
2
+ <div class="aam-feature" id="toolbar-content">
3
+ <div class="row">
4
+ <div class="col-xs-12">
5
+ <p class="aam-info">
6
+ <?php echo AAM_Backend_View_Helper::preparePhrase('[Note!] Admin Toolbar feature is not intended to restrict direct access to URLs and should be used only to remove unnecessary items from the top admin toolbar. Use [Backend Menu] tab to restrict direct access to backend pages or utilize the great power of roles and capabilities.', 'b', 'b'); ?>
7
+ </p>
8
+ </div>
9
+ </div>
10
+
11
+ <div class="aam-feature-top-actions text-right">
12
+ <a href="#" class="btn btn-xs btn-primary" id="refresh-toolbar-list"><i class="icon-arrows-cw"></i> <?php echo __('Refresh', AAM_KEY); ?></a>
13
+ </div>
14
+
15
+ <div class="row">
16
+ <div class="col-xs-12">
17
+ <div class="aam-overwrite" id="aam-toolbar-overwrite" style="display: <?php echo ($this->isOverwritten() ? 'block' : 'none'); ?>">
18
+ <span><i class="icon-check"></i> <?php echo __('Settings are customized', AAM_KEY); ?></span>
19
+ <span><a href="#" id="toolbar-reset" class="btn btn-xs btn-primary"><?php echo __('Reset To Default', AAM_KEY); ?></a>
20
+ </div>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="panel-group" id="toolbar-list" role="tablist" aria-multiselectable="true">
25
+ <?php
26
+ $first = false;
27
+ $toolbar = $this->getToolbar();
28
+ $object = AAM_Backend_Subject::getInstance()->getObject('toolbar');
29
+
30
+ //echo '<pre>'; print_r($toolbar); echo '</pre>';
31
+
32
+ if (!empty($toolbar)) { ?>
33
+ <?php foreach ($toolbar as $i => $branch) { ?>
34
+ <div class="panel panel-default">
35
+ <div class="panel-heading" role="tab" id="toolbar-<?php echo $branch->id; ?>-heading">
36
+ <h4 class="panel-title">
37
+ <a role="button" data-toggle="collapse" data-parent="#toolbar-list" href="#toolbar-<?php echo $branch->id; ?>" aria-controls="toolbar-<?php echo $branch->id; ?>" <?php if (!$first) { echo 'aria-expanded="true"'; } ?>>
38
+ <?php echo $this->normalizeTitle($branch); ?> <small class="aam-menu-capability"><?php echo str_replace(site_url(), '', $branch->href); ?></small>
39
+ </a>
40
+ <?php if ($object->has('toolbar-' . $branch->id)) { ?>
41
+ <i class="aam-panel-title-icon icon-eye-off text-danger"></i>
42
+ <?php } ?>
43
+ </h4>
44
+ </div>
45
+
46
+ <div id="toolbar-<?php echo $branch->id; ?>" class="panel-collapse collapse<?php if (!$first) { echo ' in'; $first = true; } ?>" role="tabpanel" aria-labelledby="toolbar-<?php echo $branch->id; ?>-heading">
47
+ <div class="panel-body">
48
+ <?php if (!empty($branch->children)) { ?>
49
+ <div class="row aam-inner-tab">
50
+ <?php echo ($object->has('toolbar-' . $branch->id) ? '<div class="aam-lock"></div>' : ''); ?>
51
+ <?php foreach($this->getAllChildren($branch) as $child) { ?>
52
+ <div class="col-xs-12 aam-submenu-item">
53
+ <label for="toolbar-<?php echo $child->id; ?>"><u><?php echo $this->normalizeTitle($child); ?></u><small class="aam-menu-capability"><?php echo str_replace(site_url(), '', $child->href); ?></b></small></label>
54
+ <input type="checkbox" class="aam-checkbox-danger" id="toolbar-<?php echo $child->id; ?>" data-toolbar="<?php echo $child->id; ?>"<?php echo ($object->has($child->id) ? ' checked="checked"' : ''); ?> />
55
+ <label for="toolbar-<?php echo $child->id; ?>" data-toggle="tooltip" title="<?php echo ($object->has($child->id) ? __('Uncheck to allow', AAM_KEY) : __('Check to restrict', AAM_KEY)); ?>"></label>
56
+ </div>
57
+ <?php } ?>
58
+ </div>
59
+ <hr class="aam-divider" />
60
+ <?php } ?>
61
+ <div class="row<?php echo (!empty($branch->children) ? ' aam-margin-top-xs' : ''); ?>">
62
+ <div class="col-xs-10 col-md-6 col-xs-offset-1 col-md-offset-3">
63
+ <?php if ($object->has('toolbar-' . $branch->id)) { ?>
64
+ <a href="#" class="btn btn-primary btn-sm btn-block aam-restrict-toolbar" data-toolbar="toolbar-<?php echo $branch->id; ?>" data-target="#toolbar-<?php echo $branch->id; ?>">
65
+ <i class="icon-eye"></i> <?php echo __('Show Menu', AAM_KEY); ?>
66
+ </a>
67
+ <?php } else { ?>
68
+ <a href="#" class="btn btn-danger btn-sm btn-block aam-restrict-toolbar" data-toolbar="toolbar-<?php echo $branch->id; ?>" data-target="#toolbar-<?php echo $branch->id; ?>">
69
+ <i class="icon-eye-off"></i> <?php echo __('Restrict Menu', AAM_KEY); ?>
70
+ </a>
71
+ <?php } ?>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <?php } ?>
78
+ <?php } else { ?>
79
+ <div class="row">
80
+ <div class="col-xs-12">
81
+ <p class="aam-info">
82
+ <?php echo __('The list of top admin bar items is not initialized. Click "Refresh" button above.', AAM_KEY); ?>
83
+ </p>
84
+ </div>
85
+ </div>
86
+ <?php }
87
+ ?>
88
+ </div>
89
+ </div>
90
+ <?php }
Application/Backend/phtml/partial/post-advanced-settings.phtml CHANGED
@@ -126,15 +126,9 @@
126
  <h4 class="modal-title"><?php echo __('Set Expiration', AAM_KEY); ?></h4>
127
  </div>
128
  <div class="modal-body">
129
- <p class="aam-info">
130
- The expiration criteria expects to be given a string containing a valid <a href="http://php.net/manual/en/datetime.formats.php" target="_blank">date/time format or mathematical expression</a>.
131
- Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.
132
- To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates whenever possible.<br/><br/>
133
- Examples: +2 weeks (the access will expire in 2 weeks from now); +10 hours (the access will expire in 10 hours from now); January 1st 2018; 10/08/2019
134
- </p>
135
  <div class="form-group">
136
- <label><?php echo __('Enter expiration critiria', AAM_KEY); ?></label>
137
- <input type="text" class="form-control" placeholder="<?php echo __('Enter critiria', AAM_KEY); ?>" id="aam-expire-datetime" />
138
  </div>
139
  </div>
140
  <div class="modal-footer">
126
  <h4 class="modal-title"><?php echo __('Set Expiration', AAM_KEY); ?></h4>
127
  </div>
128
  <div class="modal-body">
 
 
 
 
 
 
129
  <div class="form-group">
130
+ <div id="post-expiration-datapicker"></div>
131
+ <input type="hidden" id="aam-expire-datetime" />
132
  </div>
133
  </div>
134
  <div class="modal-footer">
Application/Backend/phtml/settings/security.phtml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (defined('AAM_KEY')) { ?>
2
+ <div class="aam-feature settings" id="settings-security-content">
3
+ <table class="table table-striped table-bordered">
4
+ <tbody>
5
+ <?php foreach($this->getList() as $id => $option) { ?>
6
+ <tr>
7
+ <td>
8
+ <span class='aam-setting-title'><?php echo $option['title']; ?></span>
9
+ <p class="aam-setting-description">
10
+ <?php echo $option['descr']; ?>
11
+ </p>
12
+ </td>
13
+ <td class="text-center">
14
+ <input data-toggle="toggle" name="<?php echo $id; ?>" id="utility-<?php echo $id; ?>" <?php echo ($option['value'] ? 'checked' : ''); ?> type="checkbox" data-on="Enabled" data-off="Disabled" data-size="small" />
15
+ </td>
16
+ </tr>
17
+ <?php } ?>
18
+ </tbody>
19
+ </table>
20
+ </div>
21
+ <?php }
Application/Backend/phtml/widget/login-backend.phtml CHANGED
@@ -9,25 +9,7 @@
9
  <input type="text" class="widefat" id="<?php echo $this->get_field_id('user-title'); ?>" name="<?php echo $this->get_field_name('user-title'); ?>" value="<?php echo esc_attr($instance['user-title']); ?>" />
10
  </p>
11
 
12
- <p>
13
- <input type="checkbox" id="<?php echo $this->get_field_id('login-timeout'); ?>" name="<?php echo $this->get_field_name('login-timeout'); ?>" value="1" <?php echo !empty($instance['login-timeout']) ? 'checked="checked"' : ""; ?> />
14
- <label for="<?php echo $this->get_field_id('login-timeout'); ?>"><strong><?php echo __('Login Timeout', AAM_KEY); ?></strong></label>
15
- <small style="line-height:1.35em; display:block; margin-top: 5px;"><?php echo __('Delay the login process for 1 second to significantly reduce the chance for brute force or dictionary attack.', AAM_KEY); ?></small>
16
- </p>
17
-
18
- <p style="margin-bottom: 1em;">
19
- <input type="checkbox" id="<?php echo $this->get_field_id('single-session'); ?>" name="<?php echo $this->get_field_name('single-session'); ?>" value="1" <?php echo !empty($instance['single-session']) ? 'checked="checked"' : ""; ?> />
20
- <label for="<?php echo $this->get_field_id('single-session'); ?>"><strong><?php echo __('One session per user', AAM_KEY); ?></strong></label>
21
- <small style="line-height:1.35em; display:block; margin-top: 5px;"><?php echo __('Automatically destroy all other sessions for a user if he/she tries to login from different location.', AAM_KEY); ?></small>
22
- </p>
23
-
24
- <p style="margin-bottom: 1em;">
25
- <input type="checkbox" id="<?php echo $this->get_field_id('brute-force-lockout'); ?>" name="<?php echo $this->get_field_name('brute-force-lockout'); ?>" value="1" <?php echo !empty($instance['brute-force-lockout']) ? 'checked="checked"' : ""; ?> />
26
- <label for="<?php echo $this->get_field_id('brute-force-lockout'); ?>"><strong><?php echo __('Brute Force Lockout', AAM_KEY); ?></strong></label>
27
- <small style="line-height:1.35em; display:block; margin-top: 5px;"><?php echo __('Automatically reject login attempts if number of unsuccessful login attempts is more than 20 over the period of 2 minutes.', AAM_KEY); ?></small>
28
- </p>
29
-
30
  <p style="background-color: #fafafa; border-left: 3px solid #337ab7; font-size: 1em; line-height: 1.35em; margin-bottom: 1em; padding: 10px; font-size: 0.8em;">
31
- <?php echo sprintf(__('For more advanced setup like login/logout redirects or custom styling, please check %sthis article%s.', AAM_KEY), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'); ?>
32
  </p>
33
  <?php }
9
  <input type="text" class="widefat" id="<?php echo $this->get_field_id('user-title'); ?>" name="<?php echo $this->get_field_name('user-title'); ?>" value="<?php echo esc_attr($instance['user-title']); ?>" />
10
  </p>
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  <p style="background-color: #fafafa; border-left: 3px solid #337ab7; font-size: 1em; line-height: 1.35em; margin-bottom: 1em; padding: 10px; font-size: 0.8em;">
13
+ <?php echo sprintf(__('For more advanced setup like login/logout redirects, security enhancement or custom styling, please refer to %sHow does AAM Secure Login works%s article.', AAM_KEY), '<a href="https://aamplugin.com/help/how-does-aam-secure-login-works" target="_blank">', '</a>'); ?>
14
  </p>
15
  <?php }
Application/Core/Compatibility.php CHANGED
@@ -59,11 +59,13 @@ class AAM_Core_Compatibility {
59
  $changes += self::normalizeOption('jwt-authentication', 'core.settings.jwtAuthentication', $config);
60
  $changes += self::normalizeOption('ms-member-access', 'core.settings.multisiteMemberAccessControl', $config);
61
  $changes += self::normalizeOption('media-access-control', 'core.settings.mediaAccessControl', $config);
62
- $changes += self::normalizeOption('check-post-visibility', 'core.settings.checkPostVisibility', $config);
63
  $changes += self::normalizeOption('manage-hidden-post-types', 'core.settings.manageHiddenPostTypes', $config);
64
  $changes += self::normalizeOption('page-category', 'core.settings.pageCategory', $config);
65
  $changes += self::normalizeOption('media-category', 'core.settings.mediaCategory', $config);
66
  $changes += self::normalizeOption('multi-category', 'core.settings.multiCategory', $config);
 
 
 
67
  $changes += self::normalizeOption('inherit-parent-post', 'core.settings.inheritParentPost', $config);
68
  //$changes += self::normalizeOption('', '', $config);
69
 
59
  $changes += self::normalizeOption('jwt-authentication', 'core.settings.jwtAuthentication', $config);
60
  $changes += self::normalizeOption('ms-member-access', 'core.settings.multisiteMemberAccessControl', $config);
61
  $changes += self::normalizeOption('media-access-control', 'core.settings.mediaAccessControl', $config);
 
62
  $changes += self::normalizeOption('manage-hidden-post-types', 'core.settings.manageHiddenPostTypes', $config);
63
  $changes += self::normalizeOption('page-category', 'core.settings.pageCategory', $config);
64
  $changes += self::normalizeOption('media-category', 'core.settings.mediaCategory', $config);
65
  $changes += self::normalizeOption('multi-category', 'core.settings.multiCategory', $config);
66
+ $changes += self::normalizeOption('login-timeout', 'core.settings.loginTimeout', $config);
67
+ $changes += self::normalizeOption('single-session', 'core.settings.singleSession', $config);
68
+ $changes += self::normalizeOption('brute-force-lockout', 'core.settings.bruteForceLockout', $config);
69
  $changes += self::normalizeOption('inherit-parent-post', 'core.settings.inheritParentPost', $config);
70
  //$changes += self::normalizeOption('', '', $config);
71
 
Application/Core/Gateway.php CHANGED
@@ -88,7 +88,7 @@ final class AAM_Core_Gateway {
88
  * @access public
89
  */
90
  public function denyAccess($params = null) {
91
- AAM_Core_API::reject();
92
  }
93
 
94
  /**
88
  * @access public
89
  */
90
  public function denyAccess($params = null) {
91
+ AAM_Core_API::reject(AAM_Core_Api_Area::get(), $params);
92
  }
93
 
94
  /**
Application/Core/Login.php CHANGED
@@ -129,7 +129,7 @@ class AAM_Core_Login {
129
  'authentication_failed',
130
  AAM_Backend_View_Helper::preparePhrase($message, 'strong')
131
  );
132
- } elseif (AAM_Core_Config::get('single-session', false)) {
133
  $sessions = WP_Session_Tokens::get_instance($user->ID);
134
 
135
  if (count($sessions->get_all()) > 1) {
@@ -174,12 +174,12 @@ class AAM_Core_Login {
174
  */
175
  public function authenticate($response) {
176
  // Login Timeout
177
- if (AAM_Core_Config::get('login-timeout', false)) {
178
  @sleep(intval(AAM_Core_Config::get('security.login.timeout', 1)));
179
  }
180
 
181
  // Brute Force Lockout
182
- if (AAM_Core_Config::get('brute-force-lockout', false)) {
183
  $this->updateLoginCounter(1);
184
  }
185
 
129
  'authentication_failed',
130
  AAM_Backend_View_Helper::preparePhrase($message, 'strong')
131
  );
132
+ } elseif (AAM_Core_Config::get('core.settings.singleSession', false)) {
133
  $sessions = WP_Session_Tokens::get_instance($user->ID);
134
 
135
  if (count($sessions->get_all()) > 1) {
174
  */
175
  public function authenticate($response) {
176
  // Login Timeout
177
+ if (AAM_Core_Config::get('core.settings.loginTimeout', false)) {
178
  @sleep(intval(AAM_Core_Config::get('security.login.timeout', 1)));
179
  }
180
 
181
  // Brute Force Lockout
182
+ if (AAM_Core_Config::get('core.settings.bruteForceLockout', false)) {
183
  $this->updateLoginCounter(1);
184
  }
185
 
Application/Core/Object/Toolbar.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Admin toolbar object
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Core_Object_Toolbar extends AAM_Core_Object {
17
+
18
+ /**
19
+ * Constructor
20
+ *
21
+ * @param AAM_Core_Subject $subject
22
+ *
23
+ * @return void
24
+ *
25
+ * @access public
26
+ */
27
+ public function __construct(AAM_Core_Subject $subject) {
28
+ parent::__construct($subject);
29
+
30
+ $option = $this->getSubject()->readOption('toolbar');
31
+
32
+ if (empty($option)) {
33
+ $option = $this->getSubject()->inheritFromParent('toolbar');
34
+ } else {
35
+ $this->setOverwritten(true);
36
+ }
37
+
38
+ $this->setOption($option);
39
+ }
40
+
41
+ /**
42
+ * Check is item defined
43
+ *
44
+ * Check if toolbar item defined in options based on the id
45
+ *
46
+ * @param string $item
47
+ *
48
+ * @return boolean
49
+ *
50
+ * @access public
51
+ */
52
+ public function has($item, $both = false) {
53
+ $options = $this->getOption();
54
+
55
+ // Step #1. Check if toolbar item is directly restricted
56
+ $direct = !empty($options[$item]);
57
+
58
+ // Step #2. Check if whole branch is restricted
59
+ $branch = ($both && !empty($options['toolbar-' . $item]));
60
+
61
+ return $direct || $branch;
62
+ }
63
+
64
+ /**
65
+ * Allow access to a specific menu
66
+ *
67
+ * @param string $menu
68
+ *
69
+ * @return boolean
70
+ *
71
+ * @access public
72
+ */
73
+ public function allow($menu) {
74
+ return $this->save($menu, 0);
75
+ }
76
+
77
+ /**
78
+ * Deny access to a specific menu
79
+ *
80
+ * @param string $menu
81
+ *
82
+ * @return boolean
83
+ *
84
+ * @access public
85
+ */
86
+ public function deny($menu) {
87
+ return $this->save($menu, 1);
88
+ }
89
+
90
+ /**
91
+ * Save menu option
92
+ *
93
+ * @return bool
94
+ *
95
+ * @access public
96
+ */
97
+ public function save($item = null, $value = null) {
98
+ if (!is_null($item)) { // keep it compatible with main Manager.save
99
+ $this->updateOptionItem($item, $value);
100
+ }
101
+
102
+ return $this->getSubject()->updateOption($this->getOption(), 'toolbar');
103
+ }
104
+
105
+ /**
106
+ * Reset default settings
107
+ *
108
+ * @return bool
109
+ *
110
+ * @access public
111
+ */
112
+ public function reset() {
113
+ return $this->getSubject()->deleteOption('toolbar');
114
+ }
115
+
116
+ }
Application/Extension/List.php CHANGED
@@ -22,7 +22,7 @@ class AAM_Extension_List {
22
  'description' => 'Get the complete list of all available premium extensions in one package. Any new premium extensions in the future will be available for no additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
- 'latest' => '3.8.2'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
@@ -31,7 +31,7 @@ class AAM_Extension_List {
31
  'description' => 'The best selling extension with the most advanced content management features for the WordPress CMS. Manage granular access to any post, page, custom post type, category, custom hierarchical taxonomy or define the default access to all your content for all users, roles and visitors.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
- 'latest' => '3.7.5'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
22
  'description' => 'Get the complete list of all available premium extensions in one package. Any new premium extensions in the future will be available for no additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
+ 'latest' => '3.8.5'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
31
  'description' => 'The best selling extension with the most advanced content management features for the WordPress CMS. Manage granular access to any post, page, custom post type, category, custom hierarchical taxonomy or define the default access to all your content for all users, roles and visitors.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
+ 'latest' => '3.7.8'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
Application/Frontend/Authorization.php CHANGED
@@ -143,13 +143,14 @@ class AAM_Frontend_Authorization {
143
  protected function checkRedirect(AAM_Core_Object_Post $post) {
144
  if ($post->has(AAM_Core_Api_Area::get() . '.redirect')) {
145
  $rule = explode('|', $post->get(AAM_Core_Api_Area::get() . '.location'));
 
146
 
147
  if (count($rule) == 1) { // TODO: legacy. Remove in Jul 2020
148
  AAM_Core_API::redirect($rule[0]);
149
  } elseif ($rule[0] == 'page') {
150
- wp_safe_redirect(get_page_link($rule[1]), 307);
151
  } elseif ($rule[0] == 'url') {
152
- wp_redirect($rule[1], 307);
153
  } elseif (($rule[0] == 'callback') && is_callable($rule[1])) {
154
  call_user_func($rule[1], $post);
155
  }
143
  protected function checkRedirect(AAM_Core_Object_Post $post) {
144
  if ($post->has(AAM_Core_Api_Area::get() . '.redirect')) {
145
  $rule = explode('|', $post->get(AAM_Core_Api_Area::get() . '.location'));
146
+ $code = apply_filters('aam-post-redirect-http-code-filter', 307);
147
 
148
  if (count($rule) == 1) { // TODO: legacy. Remove in Jul 2020
149
  AAM_Core_API::redirect($rule[0]);
150
  } elseif ($rule[0] == 'page') {
151
+ wp_safe_redirect(get_page_link($rule[1]), $code);
152
  } elseif ($rule[0] == 'url') {
153
+ wp_redirect($rule[1], $code);
154
  } elseif (($rule[0] == 'callback') && is_callable($rule[1])) {
155
  call_user_func($rule[1], $post);
156
  }
Application/Frontend/Filter.php CHANGED
@@ -39,15 +39,12 @@ class AAM_Frontend_Filter {
39
  add_action('wp', array($this, 'wp'), 999);
40
  add_action('404_template', array($this, 'themeRedirect'), 999);
41
 
42
- //important to keep this option optional for optimization reasons
43
- if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
44
- // TODO: figure out how to remove these two hooks and inject "visibility"
45
- // object instead
46
- //filter navigation pages & taxonomies
47
- add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'), 999);
48
- // filter navigation pages & taxonomies
49
- add_filter('get_pages', array($this, 'filterPages'), 999);
50
- }
51
 
52
  //widget filters
53
  add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
39
  add_action('wp', array($this, 'wp'), 999);
40
  add_action('404_template', array($this, 'themeRedirect'), 999);
41
 
42
+ // TODO: figure out how to remove these two hooks and inject "visibility"
43
+ // object instead
44
+ //filter navigation pages & taxonomies
45
+ add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'), 999);
46
+ // filter navigation pages & taxonomies
47
+ add_filter('get_pages', array($this, 'filterPages'), 999);
 
 
 
48
 
49
  //widget filters
50
  add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
Application/Frontend/Manager.php CHANGED
@@ -110,7 +110,11 @@ class AAM_Frontend_Manager {
110
  */
111
  public function printJavascript() {
112
  if (AAM_Core_Config::get('core.settings.secureLogin', true)) {
113
- wp_enqueue_script('aam-login', AAM_MEDIA . '/js/aam-login.js');
 
 
 
 
114
 
115
  //add plugin localization
116
  $locals = array(
110
  */
111
  public function printJavascript() {
112
  if (AAM_Core_Config::get('core.settings.secureLogin', true)) {
113
+ wp_enqueue_script(
114
+ 'aam-login',
115
+ AAM_MEDIA . '/js/aam-login.js',
116
+ array('jquery')
117
+ );
118
 
119
  //add plugin localization
120
  $locals = array(
Application/Shared/Manager.php CHANGED
@@ -64,23 +64,60 @@ class AAM_Shared_Manager {
64
  }
65
 
66
  // Control post visibility
67
- //important to keep this option optional for optimization reasons
68
- if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
69
- add_filter(
70
- 'posts_clauses_request',
71
- array(self::$_instance, 'filterPostQuery'),
72
- 999,
73
- 2
74
- );
75
- }
76
-
77
  //filter post content
78
- add_filter('the_content', array(self::$_instance, 'filterPostContent'), 999);
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
 
81
  return self::$_instance;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  /**
85
  *
86
  * @param type $method
@@ -132,16 +169,12 @@ class AAM_Shared_Manager {
132
  * @return type
133
  */
134
  protected function isPostFilterEnabled() {
135
- $visibility = AAM_Core_Config::get('core.settings.checkPostVisibility', true);
136
-
137
- if ($visibility) {
138
- if (AAM_Core_Api_Area::isBackend()) {
139
- $visibility = AAM_Core_Config::get('core.settings.backendAccessControl', true);
140
- } elseif (AAM_Core_Api_Area::isAPI()) {
141
- $visibility = AAM_Core_Config::get('core.settings.apiAccessControl', true);
142
- } else {
143
- $visibility = AAM_Core_Config::get('core.settings.frontendAccessControl', true);
144
- }
145
  }
146
 
147
  return $visibility;
@@ -166,7 +199,7 @@ class AAM_Shared_Manager {
166
  } elseif ($wpQuery->is_page) {
167
  $postType = 'page';
168
  } else {
169
- $postType = 'post';
170
  }
171
 
172
  if ($postType == 'any') {
64
  }
65
 
66
  // Control post visibility
67
+ add_filter(
68
+ 'posts_clauses_request',
69
+ array(self::$_instance, 'filterPostQuery'),
70
+ 999,
71
+ 2
72
+ );
73
+
 
 
 
74
  //filter post content
75
+ add_filter(
76
+ 'the_content', array(self::$_instance, 'filterPostContent'), 999
77
+ );
78
+
79
+ //filter admin toolbar
80
+ if (AAM_Core_Config::get('core.settings.backendAccessControl', true)) {
81
+ if (filter_input(INPUT_GET, 'init') !== 'toolbar') {
82
+ add_action(
83
+ 'wp_before_admin_bar_render',
84
+ array(self::$_instance, 'filterToolbar'),
85
+ 999
86
+ );
87
+ }
88
+ }
89
  }
90
 
91
  return self::$_instance;
92
  }
93
 
94
+ /**
95
+ *
96
+ * @global type $wp_admin_bar
97
+ */
98
+ public function filterToolbar() {
99
+ global $wp_admin_bar;
100
+
101
+ $toolbar = AAM::api()->getUser()->getObject('toolbar');
102
+
103
+ //echo '<pre>'; print_r($wp_admin_bar->get_nodes()); die();
104
+
105
+ foreach($wp_admin_bar->get_nodes() as $id => $node) {
106
+ if ($toolbar->has($id, true)) {
107
+ if (!empty($node->parent)) { // update parent node with # link
108
+ $parent = $wp_admin_bar->get_node($node->parent);
109
+ if ($parent && ($parent->href == $node->href)) {
110
+ $wp_admin_bar->add_node(array(
111
+ 'id' => $parent->id,
112
+ 'href' => '#'
113
+ ));
114
+ }
115
+ }
116
+ $wp_admin_bar->remove_node($id);
117
+ }
118
+ }
119
+ }
120
+
121
  /**
122
  *
123
  * @param type $method
169
  * @return type
170
  */
171
  protected function isPostFilterEnabled() {
172
+ if (AAM_Core_Api_Area::isBackend()) {
173
+ $visibility = AAM_Core_Config::get('core.settings.backendAccessControl', true);
174
+ } elseif (AAM_Core_Api_Area::isAPI()) {
175
+ $visibility = AAM_Core_Config::get('core.settings.apiAccessControl', true);
176
+ } else {
177
+ $visibility = AAM_Core_Config::get('core.settings.frontendAccessControl', true);
 
 
 
 
178
  }
179
 
180
  return $visibility;
199
  } elseif ($wpQuery->is_page) {
200
  $postType = 'page';
201
  } else {
202
+ $postType = 'any';
203
  }
204
 
205
  if ($postType == 'any') {
aam.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
- Version: 5.3.5
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
+ Version: 5.4
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
media/css/aam.css CHANGED
@@ -53,6 +53,11 @@
53
  }
54
 
55
  .icon-clock:before { content: '\e800' !important; } /* '' */
 
 
 
 
 
56
  .icon-asterisk:before { content: '\e801' !important; } /* '' */
57
  .icon-spin4:before { content: '\e802' !important; } /* '' */
58
  .icon-user-secret:before { content: '\e803' !important; } /* '' */
@@ -1473,6 +1478,382 @@ div.CodeMirror-dragcursors {
1473
  /* Help users use markselection to safely style text background */
1474
  span.CodeMirror-selectedtext { background: none; }
1475