From fa28394a8397bb7ca7cd7950a092895c56ecfc06 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 26 Aug 2022 20:46:44 +0200 Subject: [PATCH 01/32] composer.json: require ext-mbstring --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ad2dc2b..233544c 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "ext-psr": ">=1.2", "ext-redis": "*", "ext-yaml": "*", + "ext-mbstring": "*", "robmorgan/phinx": "^0.10.6", "league/oauth2-client": "^2.3", "league/oauth2-github": "^2.0", From ee5c7719cbdf9b0b7615305b909b0c504126e863 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 26 Aug 2022 20:47:27 +0200 Subject: [PATCH 02/32] app/listeners/ActivityLog.php: pass true to getClientAddress() so it looks for X-Forwarded-For header. --- app/listeners/ActivityLog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/listeners/ActivityLog.php b/app/listeners/ActivityLog.php index 6bd6a66..b12190a 100644 --- a/app/listeners/ActivityLog.php +++ b/app/listeners/ActivityLog.php @@ -67,7 +67,7 @@ class ActivityLog extends Injectable protected function _log(User $user, $message) { - $ip = (new \Phalcon\Http\Request())->getClientAddress(); + $ip = (new \Phalcon\Http\Request())->getClientAddress(true); return (new ActivityLogger())->assign([ 'user_id' => $user->getId(), From d7af32a1d7a55046a42932c176bd2ad410fc1872 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:13:19 +0200 Subject: [PATCH 03/32] app/library/Services.php: in _initSession() must pass a factory to adapter in phalcon 4 --- app/library/Services.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/library/Services.php b/app/library/Services.php index 470623e..36b3d4c 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -16,6 +16,7 @@ use Phalcon\Di\FactoryDefault as DiDefault, Phalcon\Cache\Frontend\Data as FrontendDataCache, Phalcon\Cache\Backend\Apc as BackendApcCache, Phalcon\Translate\Adapter\NativeArray as TranslateAdapter, + Phalcon\Storage\AdapterFactory as StorageAdapterFactory, Phalcon\Logger, Phalcon\Mvc\Router; @@ -195,8 +196,11 @@ class Services extends DiDefault $adapter_name = isset($data['adapter']) ? $data['adapter'] : 'Stream'; $options = $data['options']; + $serializerFactory = new \Phalcon\Storage\SerializerFactory(); + $factory = new StorageAdapterFactory($serializerFactory); + $class = 'Phalcon\Session\Adapter\\' . $adapter_name; - $adapter = new $class($options); + $adapter = new $class($factory, $options); } // Default to Stream else { From e56c8f37ead0c5947391172ea3f957332f9a4c05 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:14:04 +0200 Subject: [PATCH 04/32] app/library/Services.php: in _initSharedModelsMetadata() must pass a factory to adapter in phalcon 4 --- app/library/Services.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/library/Services.php b/app/library/Services.php index 36b3d4c..56aa404 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -17,6 +17,7 @@ use Phalcon\Di\FactoryDefault as DiDefault, Phalcon\Cache\Backend\Apc as BackendApcCache, Phalcon\Translate\Adapter\NativeArray as TranslateAdapter, Phalcon\Storage\AdapterFactory as StorageAdapterFactory, + Phalcon\Cache\AdapterFactory as CacheAdapterFactory, Phalcon\Logger, Phalcon\Mvc\Router; @@ -178,8 +179,11 @@ class Services extends DiDefault $options = $mdConfig['options']; $adapter = $mdConfig['adapter']; + $serializerFactory = new \Phalcon\Storage\SerializerFactory(); + $factory = new CacheAdapterFactory($serializerFactory); + $class = 'Phalcon\Mvc\Model\MetaData\\' . $adapter; - return new $class($options); + return new $class($factory, $options); } // Otherwise, default to Memory. From 6aeaf74a2fb3fc3a116d42ab6fb249167bb07150 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:20:53 +0200 Subject: [PATCH 05/32] package.json: set to version 1.1.0 as npm does not like 1.1 --- package-lock.json | 5 +++-- package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10c3265..54ba825 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { "name": "httpcb", - "version": "1.1", + "version": "1.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "1.1", + "name": "httpcb", + "version": "1.1.0", "license": "ISC", "devDependencies": { "@popperjs/core": "^2.11.5", diff --git a/package.json b/package.json index 1024937..446f249 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "httpcb", - "version": "1.1", + "version": "1.1.0", "description": "HTTP Callback Tool", "devDependencies": { "@popperjs/core": "^2.11.5", From 8d74cb2f060236720a6e2888f73218409e73645c Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:02:26 +0200 Subject: [PATCH 06/32] Adding app/listeners/AuthEmailListener.php --- app/listeners/AuthEmailListener.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 app/listeners/AuthEmailListener.php diff --git a/app/listeners/AuthEmailListener.php b/app/listeners/AuthEmailListener.php new file mode 100644 index 0000000..73908a0 --- /dev/null +++ b/app/listeners/AuthEmailListener.php @@ -0,0 +1,25 @@ +setUserId($user->getId()) + ->save(); + + $content = $this->di->getShared('template')->render('mail/account_activation', [ + 'link' => $activation->getActivationKey() + ]); + + $this->di->getMail()->send('Httpcb account activation', $user->getEmail(), $content); + } +} From ad2952f9fc44173d154fe49f63f24a53817468e5 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:03:28 +0200 Subject: [PATCH 07/32] app/listeners/ActivityLog.php: Adding onSentActivation --- app/listeners/ActivityLog.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/listeners/ActivityLog.php b/app/listeners/ActivityLog.php index b12190a..2af1481 100644 --- a/app/listeners/ActivityLog.php +++ b/app/listeners/ActivityLog.php @@ -65,6 +65,18 @@ class ActivityLog extends Injectable $this->_log($user, sprintf("OAuth disconnected (%s)", $providerName)); } + /** + * Fired when a activation email is sent. + * + * @param Event $event + * @param User $user + * @param string $providerName + */ + public function onSentActivation(Event $event, User $user) + { + $this->_log($user, sprintf("Activation email sent")); + } + protected function _log(User $user, $message) { $ip = (new \Phalcon\Http\Request())->getClientAddress(true); From 5b9d64c09e844f6c9234bcf1c814fb1581e2b4cd Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:04:23 +0200 Subject: [PATCH 08/32] app/config/routes.yml: Add backend-user-activation-email route --- app/config/routes.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/config/routes.yml b/app/config/routes.yml index 71b1d67..31c65e9 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -70,6 +70,9 @@ router: backend-user-edit: pattern: '/admin/user/{id:([0-9]+)}' path: backend::user::edit + backend-user-activation-email: + pattern: '/admin/user/{id:([0-9]+)}/activation' + path: backend::user::activation-email backend-user-status: pattern: '/admin/user/{id:([0-9]+)}/{type}' path: From e47aa5188e712b5fd715fbc3058262bb4e84b31c Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:05:40 +0200 Subject: [PATCH 09/32] app/library/Services.php: Attach AuthEmailListener to listen to auth events. --- app/library/Services.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/library/Services.php b/app/library/Services.php index 56aa404..b3d9cab 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -32,7 +32,8 @@ use Httpcb\Auth, use App\Listener\AccessListener, App\Listener\DispatchListener, - App\Listener\ActivityLog; + App\Listener\ActivityLog, + App\Listener\AuthEmailListener; class Services extends DiDefault { @@ -345,6 +346,7 @@ class Services extends DiDefault $eventsManager = new \Phalcon\Events\Manager(); $eventsManager->attach('user', $activityLog); $eventsManager->attach('auth', $activityLog); + $eventsManager->attach('auth', new AuthEmailListener); return $eventsManager; } From 14eb4a913766f6bf5c4b8fffa93923a725a3604e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:07:52 +0200 Subject: [PATCH 10/32] app/controllers/backend/UserController.php: Adding activationEmailAction() --- app/controllers/backend/UserController.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index c1f8206..c104381 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -97,4 +97,16 @@ class UserController extends \Phalcon\Mvc\Controller $this->flash->success('The account was: ' . $status); $this->response->redirect('/admin'); } + + public function activationEmailAction($id) + { + $user = User::findFirstById($id); + if ($user) { + $this->eventsManager->fire('auth:onSentActivation', $user); + $this->flash->success('Ativation email sent to: ' . $user->email); + } else { + $this->flash->error('Invalid user: ' . $id); + } + $this->response->redirect('/admin'); + } } From 0f5f42ca9257c8cd60418b0db78008e510913184 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:08:29 +0200 Subject: [PATCH 11/32] app/views/backend/user/form.volt: Add button for sending activation email. # Conflicts: # app/views/backend/user/form.volt --- app/views/backend/user/form.volt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/backend/user/form.volt b/app/views/backend/user/form.volt index 43d0542..ccc8157 100644 --- a/app/views/backend/user/form.volt +++ b/app/views/backend/user/form.volt @@ -56,6 +56,10 @@ {% if (user.getId()) %} {% set actions = [ 'Activate': 'Active', 'Suspend': 'Suspended', 'Delete': 'Deleted' ] %}
+ + Send activation email + + {% for label, status in actions %} {% if (user.status != status) %} From 2e98191d56440b057a26bf18370dd7ae012fb38a Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 13:09:11 +0200 Subject: [PATCH 12/32] app/controllers/ApiController.php: need to include App\Model\Data\User --- app/controllers/ApiController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/ApiController.php b/app/controllers/ApiController.php index 50a79a8..b5642f3 100644 --- a/app/controllers/ApiController.php +++ b/app/controllers/ApiController.php @@ -6,6 +6,7 @@ use App\Controller\ControllerBase, App\Model\Data\Callback as CallbackModel, App\Model\Data\Request as RequestModel, App\Model\Data\RequestMeta as RequestMetaModel, + App\Model\Data\User, App\Model\Data\UserActivation; class ApiController extends ControllerBase From ff15ee697c3206e4e52bfd769a2a6372f8f0794e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 16:40:44 +0200 Subject: [PATCH 13/32] app/config/routes.yml: Add "status" to the url for backend-user-status route. --- app/config/routes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/routes.yml b/app/config/routes.yml index 31c65e9..610ed71 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -74,7 +74,7 @@ router: pattern: '/admin/user/{id:([0-9]+)}/activation' path: backend::user::activation-email backend-user-status: - pattern: '/admin/user/{id:([0-9]+)}/{type}' + pattern: '/admin/user/{id:([0-9]+)}/status/{type}' path: module: backend controller: user From 731588587749a3c06d39cdcfe7e0f41d8980098b Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 16:38:34 +0200 Subject: [PATCH 14/32] app/config/local.sample.yml: minor fix. --- app/config/local.sample.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/local.sample.yml b/app/config/local.sample.yml index b3094eb..ce11b05 100644 --- a/app/config/local.sample.yml +++ b/app/config/local.sample.yml @@ -30,7 +30,7 @@ session: statsKey: _httpcb_sess_idx prefix: _httpcb_sess_ -#sendgrid +#sendgrid: #key: value # OAuth From c07423f600bf419eb27b8f9358b99abada3083dd Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 16:41:08 +0200 Subject: [PATCH 15/32] app/controllers/ControllerBase.php: set namespace in _forward404() --- app/controllers/ControllerBase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/ControllerBase.php b/app/controllers/ControllerBase.php index 522c8fa..d568744 100644 --- a/app/controllers/ControllerBase.php +++ b/app/controllers/ControllerBase.php @@ -18,6 +18,7 @@ class ControllerBase extends Controller protected function _forward404() { $this->dispatcher->forward(array( + 'namespace' => 'App\\Controller', 'controller' => 'error', 'action' => 'show404' )); From 1b57749a91b6ec2b3c1b5bab807b8a7f2a1c89b4 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 27 Aug 2022 11:58:26 +0200 Subject: [PATCH 16/32] app/views/backend/user/index.volt: Show badge. for status. --- app/views/backend/user/index.volt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/backend/user/index.volt b/app/views/backend/user/index.volt index 0c0a978..821fca9 100644 --- a/app/views/backend/user/index.volt +++ b/app/views/backend/user/index.volt @@ -36,7 +36,7 @@ {{ item.name }} {{ item.email }} {{ item.type | capitalize }} - {{ item.status }} + {{ item.status }} {% endfor %} From 4ff351d39d0f3dd2e1e0d8e9e5b91b180118d622 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:46:16 +0200 Subject: [PATCH 17/32] app/models/Data/User.php: Adding isSuspended() --- app/models/Data/User.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/Data/User.php b/app/models/Data/User.php index 1fe205c..7bb2cbb 100644 --- a/app/models/Data/User.php +++ b/app/models/Data/User.php @@ -265,6 +265,16 @@ class User extends Base return $this->status == self::STATUS_ACTIVE; } + /** + * Returns true if this user is suspended. + * + * @return bool + */ + public function isSuspended() + { + return $this->status == self::STATUS_SUSPENDED; + } + /** * @return mixed */ @@ -282,7 +292,7 @@ class User extends Base $this->password = $password; return $this; } - + /** * @return mixed */ From 8048b3fda8f351bd1bb0408f7031be16247044a9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:47:56 +0200 Subject: [PATCH 18/32] app/controllers/backend/UserController.php: in activationEmailAction() only send activation email to suspended users. --- app/controllers/backend/UserController.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index c104381..efaded4 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -102,8 +102,12 @@ class UserController extends \Phalcon\Mvc\Controller { $user = User::findFirstById($id); if ($user) { - $this->eventsManager->fire('auth:onSentActivation', $user); - $this->flash->success('Ativation email sent to: ' . $user->email); + if ($user->isSuspended()) { + $this->eventsManager->fire('auth:onSentActivation', $user); + $this->flash->success('Ativation email sent to: ' . $user->email); + } else { + $this->flash->error('Only suspended users can be sent activation emails.'); + } } else { $this->flash->error('Invalid user: ' . $id); } From d3e52269cdc63029a3ea0c52f653558d9f8fe5af Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:48:25 +0200 Subject: [PATCH 19/32] app/views/backend/user/form.volt: only show "Send activation email" button for suspended users. --- app/views/backend/user/form.volt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/backend/user/form.volt b/app/views/backend/user/form.volt index ccc8157..1878dd1 100644 --- a/app/views/backend/user/form.volt +++ b/app/views/backend/user/form.volt @@ -56,9 +56,12 @@ {% if (user.getId()) %} {% set actions = [ 'Activate': 'Active', 'Suspend': 'Suspended', 'Delete': 'Deleted' ] %}
+ + {% if user.isSuspended() %} Send activation email + {% endif %} {% for label, status in actions %} From 151daa8529a890ade3973a9ebfec261d985f833e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 28 Aug 2022 17:49:03 +0200 Subject: [PATCH 20/32] app/controllers/backend/UserController.php: typo fix. --- app/controllers/backend/UserController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index efaded4..61206e6 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -104,7 +104,7 @@ class UserController extends \Phalcon\Mvc\Controller if ($user) { if ($user->isSuspended()) { $this->eventsManager->fire('auth:onSentActivation', $user); - $this->flash->success('Ativation email sent to: ' . $user->email); + $this->flash->success('Activation email sent to: ' . $user->email); } else { $this->flash->error('Only suspended users can be sent activation emails.'); } From d2e7d6b67090352262a13ec4cdc8993d11058163 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 16:44:36 +0200 Subject: [PATCH 21/32] app/config/routes.yml: define all routes and use shorthand path fields. --- app/config/routes.yml | 62 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/app/config/routes.yml b/app/config/routes.yml index 610ed71..8974a32 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -4,58 +4,61 @@ router: routes: home-route: pattern: '/' - path: - controller: index - action: index + path: Index::index about-route: pattern: '/about' - path: - controller: index - action: about + path: Index::about + + # Callbacks + + cb-list: + pattern: '/callback/list' + path: Callback::list + cb-new: + pattern: '/callback/new' + path: Callback::new cb-created: pattern: '/callback/created/{id}' - path: - controller: callback - action: created + path: Callback::created + cb-show: + pattern: '/callback/show/{id}' + path: Callback::show cb-endpoint: pattern: '/cb/{id}/:params' - path: - controller: api - action: endpoint + path: Api::endpoint + + # login + login: pattern: '/login' - path: - controller: auth - action: index + path: Auth::index logout: pattern: '/logout' - path: - controller: auth - action: logout + path: Auth::logout oauth: pattern: '/login/{strategy:([a-z]+)}/:params' - path: - controller: auth - action: oauth + path: Auth::oauth oauth-disconnect: pattern: '/oauth/{provider:([a-z]+)}/disconnect' path: 'User::oauthdisconnect' oauth-disconnect-confirm: pattern: '/oauth/{provider:([a-z]+)}/disconnect/{confirm}' path: 'User::oauthdisconnect' + + # User + user-register: pattern: '/register' path: Auth::register user-settings: pattern: '/settings' - path: - controller: user - action: settings + path: User::settings + user-activity-log: + pattern: '/user/activity' + path: User::activity activation-link: pattern: '/activate/{link}' - path: - controller: api - action: activationlink + path: Api::activationlink # Backend backend-home: @@ -75,10 +78,7 @@ router: path: backend::user::activation-email backend-user-status: pattern: '/admin/user/{id:([0-9]+)}/status/{type}' - path: - module: backend - controller: user - action: status + path: backend::user::status backend-log: pattern: '/admin/log{page:/?([0-9]+)?}' path: backend::log::index From dd140ccd8addb076ffdeecc43db2bc2b4c819a5b Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 16:46:04 +0200 Subject: [PATCH 22/32] app/library/Services.php: in _initSharedRouter() Remove default routes --- app/library/Services.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/library/Services.php b/app/library/Services.php index b3d9cab..37fe922 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -319,7 +319,7 @@ class Services extends DiDefault $config = $this->get('config')->router; // Create the router - $router = new Router(); + $router = new Router(false); $router->removeExtraSlashes($config->get('removeExtraSlashes', false)); foreach($config->routes as $name => $def) { From a7a59b690a6a88307da4850a0448d1a93f18b734 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 16:46:53 +0200 Subject: [PATCH 23/32] app/library/Services.php: in _initSharedRouter() setup not found route. --- app/library/Services.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/library/Services.php b/app/library/Services.php index 37fe922..01b682c 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -336,6 +336,9 @@ class Services extends DiDefault $router->add($def->get('pattern'), $path) ->setName($name); } + + $router->notFound(['controller' => 'error', 'action' => 'show404']); + return $router; } From be4950ff88dc20325f3f9e0873ccdc76c1d8791b Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 16:52:38 +0200 Subject: [PATCH 24/32] Style fixes. --- app/controllers/ApiController.php | 2 +- app/controllers/AuthController.php | 15 +++++---- app/controllers/CallbackController.php | 12 +++---- app/controllers/IndexController.php | 1 - app/controllers/UserController.php | 9 ++++-- app/controllers/backend/UserController.php | 2 +- app/forms/CallbackCreate.php | 2 ++ app/forms/Login.php | 2 ++ app/forms/Registration.php | 14 +++++++-- app/forms/UserSettings.php | 26 +++++++++------- app/library/Acl.php | 29 +++++++++-------- app/library/Auth.php | 7 +++-- app/library/Debug.php | 5 +-- app/library/Form.php | 19 +++++++----- app/library/Menu.php | 17 +++++++--- app/library/Mvc/Model/Behavior/RandomId.php | 10 +++--- app/library/Navigation.php | 2 +- app/library/Navigation/Container.php | 7 ++--- app/library/Navigation/Node.php | 2 +- app/library/OAuth/Adapter/League.php | 2 +- app/library/Services.php | 31 +++++++++---------- app/library/Validation/Validator/Alpha.php | 4 +-- app/library/ViewHelper/AbstractHelper.php | 4 +-- app/library/ViewHelper/Icon.php | 2 +- app/library/ViewHelper/ServerUrl.php | 3 +- app/library/ViewHelper/Service.php | 4 +-- app/listeners/AccessListener.php | 4 +-- app/listeners/ActivityLog.php | 2 +- app/listeners/DispatchListener.php | 12 +++---- .../20180321115827_create_user_table.php | 2 +- .../20180321131740_create_callback_table.php | 4 +-- ...180321133533_create_request_meta_table.php | 10 ++++-- ...0321133715_create_request_object_table.php | 8 +++-- .../20180611202847_password_link.php | 8 ++--- .../20180814172405_user_split_name.php | 6 ++-- app/migrations/20181003134001_user_type.php | 2 +- app/models/Data/Base.php | 2 +- app/models/Data/Callback.php | 4 +-- app/models/Data/Request.php | 2 +- app/models/Data/RequestMeta.php | 6 ++-- app/models/Data/User.php | 12 +++---- app/models/Data/UserActivation.php | 16 +++++----- app/modules/Base.php | 3 +- 43 files changed, 187 insertions(+), 149 deletions(-) diff --git a/app/controllers/ApiController.php b/app/controllers/ApiController.php index b5642f3..1d2f3f4 100644 --- a/app/controllers/ApiController.php +++ b/app/controllers/ApiController.php @@ -59,7 +59,7 @@ class ApiController extends ControllerBase */ public function activationLinkAction($id) { - $link = UserActivation::findFirst(['activation_key = ?0', 'bind' => [ $id ]]); + $link = UserActivation::findFirst(['activation_key = ?0', 'bind' => [$id]]); if ($link) { if ($link->isValid()) { diff --git a/app/controllers/AuthController.php b/app/controllers/AuthController.php index 0fb0e47..95adae8 100644 --- a/app/controllers/AuthController.php +++ b/app/controllers/AuthController.php @@ -33,8 +33,8 @@ class AuthController extends ControllerBase } else { $msg = '
    '; - foreach($form->getMessages() as $message) { - $msg .= '
  • ' . $message->getField() . ' '. $message->getMessage() . '
  • '; + foreach ($form->getMessages() as $message) { + $msg .= '
  • ' . $message->getField() . ' ' . $message->getMessage() . '
  • '; } $msg .= '
'; @@ -47,7 +47,7 @@ class AuthController extends ControllerBase public function oauthAction($provider_name) { - $client = $this->getDI()->get('oauth', [ $provider_name ]); + $client = $this->getDI()->get('oauth', [$provider_name]); $code = $this->request->get('code'); $state = $this->request->get('state'); @@ -92,7 +92,7 @@ class AuthController extends ControllerBase // User is logged in. $this->response->redirect('/'); } - } catch(\Exception $e) { + } catch (\Exception $e) { throw $e; $this->flash->message('error', 'Failed to authenticate.'); if ($this->auth->getUser()) { @@ -118,8 +118,11 @@ class AuthController extends ControllerBase } $user = new User(); - $user->assign($data->toArray(), null, - [ 'email', 'username', 'firstname', 'lastname' ]); + $user->assign( + $data->toArray(), + null, + ['email', 'username', 'firstname', 'lastname'] + ); $form = new RegistrationForm($user); diff --git a/app/controllers/CallbackController.php b/app/controllers/CallbackController.php index 83376ee..07d4994 100644 --- a/app/controllers/CallbackController.php +++ b/app/controllers/CallbackController.php @@ -55,24 +55,23 @@ class CallbackController extends ControllerBase return $this->response->redirect(array( 'for' => 'cb-created', - 'id' => $callback->getPublicId())); + 'id' => $callback->getPublicId() + )); } else { - foreach($callback->getMessages() as $msg) { + foreach ($callback->getMessages() as $msg) { $this->flash->error($msg); } } } else { $msg = '
    '; - foreach($form->getMessages() as $message) { - $msg .= '
  • ' . $message->getField() . ': '. $message->getMessage() . '
  • '; + foreach ($form->getMessages() as $message) { + $msg .= '
  • ' . $message->getField() . ': ' . $message->getMessage() . '
  • '; } $msg .= '
'; $this->flash->message('error', $msg); } - - } $this->view->form = $form; @@ -85,7 +84,6 @@ class CallbackController extends ControllerBase { $row = CallbackModel::get($id); if (!$row) { - } $this->view->id = $id; } diff --git a/app/controllers/IndexController.php b/app/controllers/IndexController.php index c44cbb1..f0ac84f 100644 --- a/app/controllers/IndexController.php +++ b/app/controllers/IndexController.php @@ -15,4 +15,3 @@ class IndexController extends ControllerBase { } } - diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index 414f406..158259f 100644 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -44,8 +44,11 @@ class UserController extends ControllerBase ]); // Send the email. - $this->di->getMail()->send('Httpcb password activation', - $user->getEmail(), $content); + $this->di->getMail()->send( + 'Httpcb password activation', + $user->getEmail(), + $content + ); $msg = "For security reasons. Before a password can be created " . "a email has been sent to {$user->getEmail()} with " @@ -137,7 +140,7 @@ class UserController extends ControllerBase $msg = '

You are about to unlink the last OAuth provider.' . ' Your only login option will be password if you do this.

' - . '

Are you sure? Yes

'; + . '

Are you sure? Yes

'; $this->flash->message('warning', $msg); $this->response->redirect('/settings'); diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index 61206e6..8737728 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -17,7 +17,7 @@ class UserController extends \Phalcon\Mvc\Controller */ public function indexAction($page = 1) { - $paginator = User::getPaginationList($page,15); + $paginator = User::getPaginationList($page, 15); $this->view->pagination_url = '/admin/user/list/'; $this->view->page = $paginator->paginate(); diff --git a/app/forms/CallbackCreate.php b/app/forms/CallbackCreate.php index 11115bb..dbf2e83 100644 --- a/app/forms/CallbackCreate.php +++ b/app/forms/CallbackCreate.php @@ -7,12 +7,14 @@ use Phalcon\Forms\Form; /** * Element types */ + use Phalcon\Forms\Element\Text; use Phalcon\Forms\Element\Submit; /** * Validators */ + use Phalcon\Validation\Validator\StringLength; class CallbackCreate extends Form diff --git a/app/forms/Login.php b/app/forms/Login.php index f3c1ce0..fa639b3 100644 --- a/app/forms/Login.php +++ b/app/forms/Login.php @@ -7,6 +7,7 @@ use Phalcon\Forms\Form; /** * Element types */ + use Phalcon\Forms\Element\Text; use Phalcon\Forms\Element\Password; use Phalcon\Forms\Element\Submit; @@ -14,6 +15,7 @@ use Phalcon\Forms\Element\Submit; /** * Validators */ + use Phalcon\Validation\Validator\PresenceOf; use Phalcon\Validation\Validator\Email as EmailValidator; use Phalcon\Validation\Validator\StringLength; diff --git a/app/forms/Registration.php b/app/forms/Registration.php index 9e8d292..092b2c7 100644 --- a/app/forms/Registration.php +++ b/app/forms/Registration.php @@ -5,16 +5,19 @@ namespace App\Form; /** * Models */ + use App\Model\Data\User; /** * Phalcon Form */ + use Httpcb\Form as FormBase; /** * Element types */ + use Phalcon\Forms\Element\Text, Phalcon\Forms\Element\Password, Phalcon\Forms\Element\Submit; @@ -22,6 +25,7 @@ use Phalcon\Forms\Element\Text, /** * Validators */ + use Phalcon\Validation, Phalcon\Validation\Validator\Callback as CallbackValidator, Phalcon\Validation\Validator\Alnum as AlnumValidator, @@ -54,7 +58,9 @@ class Registration extends FormBase 'messageMinimum' => 'Username must be at least :min characters long.', ]), new CallbackValidator([ - 'callback' => function($data) { return User::findFirstByUsername($data['username']) === false; }, + 'callback' => function ($data) { + return User::findFirstByUsername($data['username']) === false; + }, 'message' => 'The username already exists.', 'attribute' => 'username', ]) @@ -63,7 +69,7 @@ class Registration extends FormBase $this->add($username); // Names - foreach([ 'first-name' => 'Firstname', 'last-name' => 'Lastname' ] as $id => $label) { + foreach (['first-name' => 'Firstname', 'last-name' => 'Lastname'] as $id => $label) { $name = new Text($id, array( 'class' => 'form-control', @@ -87,7 +93,9 @@ class Registration extends FormBase $email->addValidators([ new CallbackValidator([ - 'callback' => function($data) { return User::findFirstByEmail($data['email']) === false; }, + 'callback' => function ($data) { + return User::findFirstByEmail($data['email']) === false; + }, 'message' => 'This email already exist.', ]) ]); diff --git a/app/forms/UserSettings.php b/app/forms/UserSettings.php index 4eae39f..d86459e 100644 --- a/app/forms/UserSettings.php +++ b/app/forms/UserSettings.php @@ -5,16 +5,19 @@ namespace App\Form; /** * Models */ + use App\Model\Data\User as UserModel; /** * Form */ + use Httpcb\Form as FormBase; /** * Element types */ + use Phalcon\Forms\Element\Text, Phalcon\Forms\Element\Password, Phalcon\Forms\Element\Submit; @@ -22,6 +25,7 @@ use Phalcon\Forms\Element\Text, /** * Validators */ + use Phalcon\Validation\Validator\Callback as CallbackValidator, Phalcon\Validation\Validator\Uniqueness as UniquenessValidator, Phalcon\Validation\Validator\Alnum as AlnumValidator, @@ -56,15 +60,15 @@ class UserSettings extends FormBase // Id if ($entity && $entity->getId()) { - $id = new Text('id', array( - 'class' => 'form-control', - 'readonly' => '', - 'disabled' => 'disabled', - )); + $id = new Text('id', array( + 'class' => 'form-control', + 'readonly' => '', + 'disabled' => 'disabled', + )); $id->addValidator(new IdenticalValidator([ 'accepted' => $entity->getId(), - 'allowEmpty' => true + 'allowEmpty' => true ])); $id->setLabel('ID'); @@ -86,7 +90,7 @@ class UserSettings extends FormBase ); if ($entity && strlen($entity->getUsername())) { - $validator_options['except'] = [ $entity->getUsername() ]; + $validator_options['except'] = [$entity->getUsername()]; } $username->addValidators([ @@ -116,12 +120,12 @@ class UserSettings extends FormBase 'class' => 'form-control', 'placeholder' => 'Email', 'readonly' => '', - 'disabled' => 'disabled', + 'disabled' => 'disabled', )); $email->addValidator(new IdenticalValidator([ 'accepted' => $entity->getEmail(), - 'allowEmpty' => true + 'allowEmpty' => true ])); } else { $email = new Text('email', array( @@ -136,7 +140,7 @@ class UserSettings extends FormBase ]; if ($entity && strlen($entity->getEmail())) { - $validator_options['except'] = [ $entity->getEmail() ]; + $validator_options['except'] = [$entity->getEmail()]; } $email->addValidators([ @@ -191,7 +195,7 @@ class UserSettings extends FormBase if ($this->_admin === false && $entity && strlen($entity->getPassword()) > 0) { $validation->add('passwordCurrent', new CallbackValidator([ - 'callback' => function($data) { + 'callback' => function ($data) { $new_pw = $data['passwordNew']; if (strlen($new_pw) > 0) { $value = $data['passwordCurrent']; diff --git a/app/library/Acl.php b/app/library/Acl.php index cfaada1..8c4562b 100644 --- a/app/library/Acl.php +++ b/app/library/Acl.php @@ -3,7 +3,7 @@ namespace Httpcb; use Phalcon\Config, - Phalcon\Acl\Enum, + Phalcon\Acl\Enum, Phalcon\Acl\Role, Phalcon\Acl\Adapter\Memory as Adapter; @@ -40,7 +40,7 @@ class Acl $pos = strpos($resource, '/'); if ($pos !== false) { // Construct the wildcard resource. - $wildcard = substr($resource, 0, $pos+1) . '*'; + $wildcard = substr($resource, 0, $pos + 1) . '*'; // If we have this wildcard resource, check against that instead. if ($this->hasResource($wildcard)) { @@ -62,7 +62,7 @@ class Acl public function fromConfig(Config $config) { // Add roles. - foreach($config->roles as $name => $def) { + foreach ($config->roles as $name => $def) { $inherits = null; $description = null; @@ -70,7 +70,6 @@ class Acl if ($def instanceof Config) { $inherits = $def->get('inherits'); $description = $def->get('description'); - } $role = new Role($name, $description); @@ -78,33 +77,33 @@ class Acl } // Zones - foreach($config->zones as $name => $resources) { + foreach ($config->zones as $name => $resources) { if (!($resources instanceof Config)) { - $resources = new Config([ $resources ]); + $resources = new Config([$resources]); } - foreach($resources as $resource) { + foreach ($resources as $resource) { $this->_adapter->addComponent($resource, 'All'); } } // Grant access for roles and resources. - foreach($config->roles as $name => $def) { + foreach ($config->roles as $name => $def) { $zones = $def->get('allowed-zones', []); if (is_string($zones)) { - $zones = [ $zones ]; + $zones = [$zones]; } - foreach($zones as $zone) { + foreach ($zones as $zone) { $resources = $config->zones->get($zone); - if (!($resources instanceof Config)) { - $resources = new Config([ $resources ]); - } - foreach($resources as $resource) { - $this->_adapter->allow($name, $resource, 'All'); + if (!($resources instanceof Config)) { + $resources = new Config([$resources]); + } + foreach ($resources as $resource) { + $this->_adapter->allow($name, $resource, 'All'); } } } diff --git a/app/library/Auth.php b/app/library/Auth.php index 7c837d0..81750da 100644 --- a/app/library/Auth.php +++ b/app/library/Auth.php @@ -63,8 +63,11 @@ class Auth extends Injectable $this->setIdentity($user->getId()); - $this->eventsManager->fire('auth:onLogin', $this, - "OAuth {$data->getProvider()}"); + $this->eventsManager->fire( + 'auth:onLogin', + $this, + "OAuth {$data->getProvider()}" + ); return new Result(Result::SUCCESS); diff --git a/app/library/Debug.php b/app/library/Debug.php index 336e7ba..f41e09a 100644 --- a/app/library/Debug.php +++ b/app/library/Debug.php @@ -2,12 +2,13 @@ namespace Httpcb; -class Debug { +class Debug +{ public static function dump($var, $label = null, $echo = true) { // format the label - $label = ($label===null) ? '' : rtrim($label) . ' '; + $label = ($label === null) ? '' : rtrim($label) . ' '; // var_dump the variable into a buffer and keep the output ob_start(); var_dump($var); diff --git a/app/library/Form.php b/app/library/Form.php index 978c904..80755e3 100644 --- a/app/library/Form.php +++ b/app/library/Form.php @@ -11,7 +11,7 @@ class Form extends FormBase { $options = [ 'label-class' => 'col-form-label text-end', - 'class' => [ 'col-sm-10' ], + 'class' => ['col-sm-10'], 'message' => '' ]; @@ -31,7 +31,7 @@ class Form extends FormBase if ($len === 'full') { $options['class'] = []; } else { - $options['class'] = [ 'col-sm-' . $len ]; + $options['class'] = ['col-sm-' . $len]; } unset($opt['length']); @@ -42,10 +42,10 @@ class Form extends FormBase protected function _render(AbstractElement $ele, $opt) { - $classes = ['class' => 'form-control']; - if ($ele->hasMessages()) { - $classes['class'] .= ' is-invalid'; - } + $classes = ['class' => 'form-control']; + if ($ele->hasMessages()) { + $classes['class'] .= ' is-invalid'; + } $xhtml = ''; @@ -53,14 +53,17 @@ class Form extends FormBase $xhtml .= sprintf( '', - $opt['label-class'], $ele->getName(), $ele->getLabel()); + $opt['label-class'], + $ele->getName(), + $ele->getLabel() + ); } $xhtml .= '
' . $ele->render($classes); if ($ele->hasMessages()) { - $msg = $ele->getMessages()->current(); + $msg = $ele->getMessages()->current(); $xhtml .= '' . $msg . ''; } diff --git a/app/library/Menu.php b/app/library/Menu.php index 01512fe..f16b462 100644 --- a/app/library/Menu.php +++ b/app/library/Menu.php @@ -90,7 +90,7 @@ class Menu extends Tag { $xhtml = ''; - foreach($nodes as $node) { + foreach ($nodes as $node) { $xhtml .= $this->_renderNode($node, $depth, $max_depth); } @@ -126,15 +126,22 @@ class Menu extends Tag return $xhtml; } - $xhtml = self::tagHtml('li', $node->isActive() + $xhtml = self::tagHtml( + 'li', + $node->isActive() ? array('class' => $this->_activeClass) : null, - false, false, true); + false, + false, + true + ); // Generate the link. $xhtml .= self::linkTo($node->getHref(), $node->getCaption()); - if ($node->isActive() && $node->hasChildren() - && ($max_depth === null || $depth < $max_depth)) { + if ( + $node->isActive() && $node->hasChildren() + && ($max_depth === null || $depth < $max_depth) + ) { $xhtml .= $this->_renderMenu($node->getChildren(), $depth + 1, $max_depth); } diff --git a/app/library/Mvc/Model/Behavior/RandomId.php b/app/library/Mvc/Model/Behavior/RandomId.php index 185c188..e5d7173 100644 --- a/app/library/Mvc/Model/Behavior/RandomId.php +++ b/app/library/Mvc/Model/Behavior/RandomId.php @@ -44,10 +44,10 @@ class RandomId extends Behavior implements BehaviorInterface */ public function notify($type, \Phalcon\Mvc\ModelInterface $model) { - switch($type) { - case 'beforeValidationOnCreate' : - $this->generateId($model); - break; + switch ($type) { + case 'beforeValidationOnCreate': + $this->generateId($model); + break; } } @@ -69,7 +69,7 @@ class RandomId extends Behavior implements BehaviorInterface if ($model->$field === null) { $random = new \Phalcon\Security\Random(); - for($i = 0; $i < 3; $i++) { + for ($i = 0; $i < 3; $i++) { $id = substr($random->base64Safe(), 0, $len); $count = $model->count(array( diff --git a/app/library/Navigation.php b/app/library/Navigation.php index 6050c71..498c7c1 100644 --- a/app/library/Navigation.php +++ b/app/library/Navigation.php @@ -11,7 +11,7 @@ class Navigation extends Navigation\Container */ public function __construct($config) { - foreach($config as $node) { + foreach ($config as $node) { $this->addChild($node); } } diff --git a/app/library/Navigation/Container.php b/app/library/Navigation/Container.php index f7a6da7..3495608 100644 --- a/app/library/Navigation/Container.php +++ b/app/library/Navigation/Container.php @@ -38,7 +38,7 @@ class Container $node = new Node(); - foreach($child as $k => $v) { + foreach ($child as $k => $v) { if ($k == 'children') { continue; @@ -49,7 +49,7 @@ class Container if (isset($child['children'])) { - foreach($child['children'] as $c_data) { + foreach ($child['children'] as $c_data) { $node->addChild($c_data); } } @@ -75,10 +75,9 @@ class Container */ public function addChildren($children) { - foreach($children as $child) { + foreach ($children as $child) { $this->addChild($child); } return $this; } } - diff --git a/app/library/Navigation/Node.php b/app/library/Navigation/Node.php index fb1f6b6..6fdbf7f 100644 --- a/app/library/Navigation/Node.php +++ b/app/library/Navigation/Node.php @@ -225,7 +225,7 @@ class Node extends Container } // first. Check children. - foreach($this->getChildren() as $child) { + foreach ($this->getChildren() as $child) { if ($child->isActive() == true) { $this->setActive(true); diff --git a/app/library/OAuth/Adapter/League.php b/app/library/OAuth/Adapter/League.php index e9b8829..ccf4ae4 100644 --- a/app/library/OAuth/Adapter/League.php +++ b/app/library/OAuth/Adapter/League.php @@ -61,7 +61,7 @@ class League implements AdapterInterface try { $reflection = new \ReflectionClass($this->_provider); return $reflection->getShortName(); - } catch(\ReflectionException $ex) { + } catch (\ReflectionException $ex) { return ''; } } diff --git a/app/library/Services.php b/app/library/Services.php index 01b682c..1a3a625 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -12,7 +12,7 @@ use Phalcon\Di\FactoryDefault as DiDefault, Phalcon\Flash\Direct as FlashDirect, Phalcon\Mvc\Model\Metadata\Memory as MemoryMetaData, Phalcon\Mvc\Model\MetaData\Apc as ApcMetaData, - Phalcon\Mvc\ViewBaseInterface, + Phalcon\Mvc\ViewBaseInterface, Phalcon\Cache\Frontend\Data as FrontendDataCache, Phalcon\Cache\Backend\Apc as BackendApcCache, Phalcon\Translate\Adapter\NativeArray as TranslateAdapter, @@ -44,13 +44,12 @@ class Services extends DiDefault $reflection = new \ReflectionObject($this); $methods = $reflection->getMethods(\ReflectionMethod::IS_PROTECTED); - foreach($methods as $method) { + foreach ($methods as $method) { - if (substr($method->getName(),0, 11) == '_initShared') { + if (substr($method->getName(), 0, 11) == '_initShared') { $service = lcfirst(substr($method->getName(), 11)); $this->setShared($service, $method->getClosure($this)); - } - else if (substr($method->getName(),0, 5) == '_init') { + } else if (substr($method->getName(), 0, 5) == '_init') { $service = lcfirst(substr($method->getName(), 5)); $this->set($service, $method->getClosure($this)); } @@ -84,7 +83,7 @@ class Services extends DiDefault try { $tmp = new Config($basePath . $file); $config->merge($tmp); - } catch(\Phalcon\Config\Exception $e) { + } catch (\Phalcon\Config\Exception $e) { // Sometime went wrong. Log here? } } @@ -118,7 +117,7 @@ class Services extends DiDefault $eventsManager = new \Phalcon\Events\Manager(); - $eventsManager->attach("dispatch", function($event, $dispatcher) { + $eventsManager->attach("dispatch", function ($event, $dispatcher) { $actionName = lcfirst(\Phalcon\Text::camelize($dispatcher->getActionName(), '-_')); $dispatcher->setActionName($actionName); }); @@ -194,7 +193,7 @@ class Services extends DiDefault protected function _initSession() { $config = $this->get('config'); - $session = new \Phalcon\Session\Manager(); + $session = new \Phalcon\Session\Manager(); if (isset($config->session)) { $data = $config->session->toArray(); @@ -212,7 +211,7 @@ class Services extends DiDefault $adapter = new \Phalcon\Session\Adapter\Stream(); } - $session->setAdapter($adapter); + $session->setAdapter($adapter); // Start session. $session->start(); @@ -228,7 +227,7 @@ class Services extends DiDefault $view = new View(); - $view->setViewsDir([ $config->application->viewsDir ]); + $view->setViewsDir([$config->application->viewsDir]); $view->setLayoutsDir('_layouts/'); $view->setPartialsDir('_partials/'); @@ -322,7 +321,7 @@ class Services extends DiDefault $router = new Router(false); $router->removeExtraSlashes($config->get('removeExtraSlashes', false)); - foreach($config->routes as $name => $def) { + foreach ($config->routes as $name => $def) { if (!($def instanceof \Phalcon\Config)) { continue; @@ -366,10 +365,10 @@ class Services extends DiDefault protected function _initSharedLogger() { - $path = $this->get('config')->application->logDir; - return new \Phalcon\Logger('default', [ - 'main' => new \Phalcon\Logger\Adapter\Stream($path . 'app.txt') - ]); + $path = $this->get('config')->application->logDir; + return new \Phalcon\Logger('default', [ + 'main' => new \Phalcon\Logger\Adapter\Stream($path . 'app.txt') + ]); } protected function _initTemplate() @@ -379,7 +378,7 @@ class Services extends DiDefault $view = new SimpleView(); $view->setViewsDir($config->application->templateDir); $view->registerEngines([ - '.volt' => function (ViewBaseInterface $view) use ($config) { + '.volt' => function (ViewBaseInterface $view) use ($config) { $volt = new VoltEngine($view, $this); $volt->setOptions(array( diff --git a/app/library/Validation/Validator/Alpha.php b/app/library/Validation/Validator/Alpha.php index 540766f..095c75a 100644 --- a/app/library/Validation/Validator/Alpha.php +++ b/app/library/Validation/Validator/Alpha.php @@ -21,7 +21,7 @@ class Alpha extends AbstractValidator * @param string $field * @return bool */ - public function validate(\Phalcon\Validation $validation, $field) : bool + public function validate(\Phalcon\Validation $validation, $field): bool { $allowSpace = $this->getOption('allowSpace', false); @@ -44,7 +44,7 @@ class Alpha extends AbstractValidator $message = $validation->getDefaultMessage('Alpha'); } - $replace = [ ":field" => $label ]; + $replace = [":field" => $label]; $code = $this->getOption("code"); if (is_array($code)) { diff --git a/app/library/ViewHelper/AbstractHelper.php b/app/library/ViewHelper/AbstractHelper.php index ff5fe01..a7c9617 100644 --- a/app/library/ViewHelper/AbstractHelper.php +++ b/app/library/ViewHelper/AbstractHelper.php @@ -14,7 +14,7 @@ abstract class AbstractHelper implements InjectionAwareInterface * * @param DiInterface $container */ - public function setDI(DiInterface $container) : void + public function setDI(DiInterface $container): void { $this->_di = $container; } @@ -24,7 +24,7 @@ abstract class AbstractHelper implements InjectionAwareInterface * * @return DiInterface */ - public function getDI() : DiInterface + public function getDI(): DiInterface { return $this->_di; } diff --git a/app/library/ViewHelper/Icon.php b/app/library/ViewHelper/Icon.php index 8657d40..18b87b8 100644 --- a/app/library/ViewHelper/Icon.php +++ b/app/library/ViewHelper/Icon.php @@ -27,7 +27,7 @@ class Icon extends AbstractHelper if (is_array($args)) { - foreach($args as $arg) { + foreach ($args as $arg) { $classes[] .= 'fa-' . $arg; } } diff --git a/app/library/ViewHelper/ServerUrl.php b/app/library/ViewHelper/ServerUrl.php index 51ad62e..90acef2 100644 --- a/app/library/ViewHelper/ServerUrl.php +++ b/app/library/ViewHelper/ServerUrl.php @@ -33,7 +33,8 @@ class ServerUrl extends AbstractHelper // remove port if it's the default port. if (($scheme == 'http' && $port == 80) - || ($scheme == 'https' && $port == 443)) { + || ($scheme == 'https' && $port == 443) + ) { $port = null; } diff --git a/app/library/ViewHelper/Service.php b/app/library/ViewHelper/Service.php index 1e20f72..a0662bc 100644 --- a/app/library/ViewHelper/Service.php +++ b/app/library/ViewHelper/Service.php @@ -16,7 +16,7 @@ class Service implements InjectionAwareInterface * * @param DiInterface $container */ - public function setDI(DiInterface $container) : void + public function setDI(DiInterface $container): void { $this->_di = $container; } @@ -26,7 +26,7 @@ class Service implements InjectionAwareInterface * * @return DiInterface */ - public function getDI() : DiInterface + public function getDI(): DiInterface { return $this->_di; } diff --git a/app/listeners/AccessListener.php b/app/listeners/AccessListener.php index 4f6099a..4039f8e 100644 --- a/app/listeners/AccessListener.php +++ b/app/listeners/AccessListener.php @@ -3,7 +3,7 @@ namespace App\Listener; use Phalcon\Di\Injectable, - Phalcon\Events\Event, + Phalcon\Events\Event, Phalcon\Mvc\Dispatcher, Phalcon\Mvc\Dispatcher\Exception as DispatcherException; @@ -22,7 +22,7 @@ class AccessListener extends Injectable * @return bool * @throws DispatcherException */ - public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher) : bool + public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher): bool { // If we have an identity, fetch type from authed user. if ($this->auth->hasIdentity()) { diff --git a/app/listeners/ActivityLog.php b/app/listeners/ActivityLog.php index 2af1481..906b3be 100644 --- a/app/listeners/ActivityLog.php +++ b/app/listeners/ActivityLog.php @@ -81,7 +81,7 @@ class ActivityLog extends Injectable { $ip = (new \Phalcon\Http\Request())->getClientAddress(true); - return (new ActivityLogger())->assign([ + return (new ActivityLogger())->assign([ 'user_id' => $user->getId(), 'ip' => $ip, 'message' => $message diff --git a/app/listeners/DispatchListener.php b/app/listeners/DispatchListener.php index 650c4e3..1be9f90 100644 --- a/app/listeners/DispatchListener.php +++ b/app/listeners/DispatchListener.php @@ -4,7 +4,7 @@ namespace App\Listener; use Exception, Phalcon\Events\Event, - Phalcon\Di\Injectable, + Phalcon\Di\Injectable, Phalcon\Mvc\Dispatcher, Phalcon\Mvc\Dispatcher\Exception as DispatcherException; @@ -38,11 +38,11 @@ class DispatchListener extends Injectable // was that an controller or action was not found. if ($exception instanceof DispatcherException) { switch ($exception->getCode()) { - case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND : - case Dispatcher::EXCEPTION_ACTION_NOT_FOUND : - // in this case, forward to 404 page. - $dispatcher->forward($this->_route_notfound); - return false; + case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND: + case Dispatcher::EXCEPTION_ACTION_NOT_FOUND: + // in this case, forward to 404 page. + $dispatcher->forward($this->_route_notfound); + return false; } } diff --git a/app/migrations/20180321115827_create_user_table.php b/app/migrations/20180321115827_create_user_table.php index c79e002..898a15c 100644 --- a/app/migrations/20180321115827_create_user_table.php +++ b/app/migrations/20180321115827_create_user_table.php @@ -21,7 +21,7 @@ class CreateUserTable extends AbstractMigration $table->addColumn('status', 'enum', [ 'null' => false, 'default' => 'Active', - 'values' => [ 'Active', 'Deleted', 'Suspended'] + 'values' => ['Active', 'Deleted', 'Suspended'] ]); $table->addColumn('password', 'string', [ diff --git a/app/migrations/20180321131740_create_callback_table.php b/app/migrations/20180321131740_create_callback_table.php index 9de7884..96e9de0 100644 --- a/app/migrations/20180321131740_create_callback_table.php +++ b/app/migrations/20180321131740_create_callback_table.php @@ -11,11 +11,11 @@ class CreateCallbackTable extends AbstractMigration $table->addColumn('public_id', 'string', [ 'length' => 12, 'null' => false, - ])->addIndex('public_id', [ 'name' => 'UNIQUE_public_id', 'unique' => true ]); + ])->addIndex('public_id', ['name' => 'UNIQUE_public_id', 'unique' => true]); $table->addColumn('userid', 'integer', [ 'null' => true, - ])->addForeignKey('userid', 'user', ['id'], [ 'constraint' => 'FK_user' ]); + ])->addForeignKey('userid', 'user', ['id'], ['constraint' => 'FK_user']); $table->addColumn('name', 'string', [ 'length' => 64, diff --git a/app/migrations/20180321133533_create_request_meta_table.php b/app/migrations/20180321133533_create_request_meta_table.php index 124eb5f..249ac14 100644 --- a/app/migrations/20180321133533_create_request_meta_table.php +++ b/app/migrations/20180321133533_create_request_meta_table.php @@ -10,8 +10,12 @@ class CreateRequestMetaTable extends AbstractMigration $table = $this->table('request_meta'); $table->addColumn('callbackid', 'integer'); - $table->addForeignKey('callbackid', 'callback', [ 'id' ], - [ 'constraint' => 'FK_callback' ]); + $table->addForeignKey( + 'callbackid', + 'callback', + ['id'], + ['constraint' => 'FK_callback'] + ); $table->addColumn('source_ip', 'string', [ 'limit' => 50, @@ -21,7 +25,7 @@ class CreateRequestMetaTable extends AbstractMigration $table->addColumn('method', 'enum', [ 'null' => false, 'default' => 'GET', - 'values' => [ 'GET', 'POST' ] + 'values' => ['GET', 'POST'] ]); $table->addColumn('uri', 'string', [ diff --git a/app/migrations/20180321133715_create_request_object_table.php b/app/migrations/20180321133715_create_request_object_table.php index 29aea46..fcd422a 100644 --- a/app/migrations/20180321133715_create_request_object_table.php +++ b/app/migrations/20180321133715_create_request_object_table.php @@ -9,8 +9,12 @@ class CreateRequestObjectTable extends AbstractMigration { $table = $this->table('request_object'); - $table->addForeignKey('id', 'request_meta', ['id'], - [ 'constraint' => 'FK_request_meta' ]); + $table->addForeignKey( + 'id', + 'request_meta', + ['id'], + ['constraint' => 'FK_request_meta'] + ); $table->addColumn('headers', 'blob', [ 'null' => true, diff --git a/app/migrations/20180611202847_password_link.php b/app/migrations/20180611202847_password_link.php index 843dd11..1820c77 100644 --- a/app/migrations/20180611202847_password_link.php +++ b/app/migrations/20180611202847_password_link.php @@ -8,11 +8,11 @@ class PasswordLink extends AbstractMigration public function up() { $this->table('password_link') - ->addColumn('public_id', 'string', ['length' => 12 ]) + ->addColumn('public_id', 'string', ['length' => 12]) ->addColumn('user_id', 'integer') - ->addForeignKey('user_id', 'user', ['id'], [ 'constraint' => 'FK_password_link_user' ]) - ->addColumn('date', 'datetime', [ 'default' => 'CURRENT_TIMESTAMP' ]) - ->addColumn('password', 'string', [ 'limit' => 255, 'null' => true ]) + ->addForeignKey('user_id', 'user', ['id'], ['constraint' => 'FK_password_link_user']) + ->addColumn('date', 'datetime', ['default' => 'CURRENT_TIMESTAMP']) + ->addColumn('password', 'string', ['limit' => 255, 'null' => true]) ->save(); } } diff --git a/app/migrations/20180814172405_user_split_name.php b/app/migrations/20180814172405_user_split_name.php index f903fd1..3d2c272 100644 --- a/app/migrations/20180814172405_user_split_name.php +++ b/app/migrations/20180814172405_user_split_name.php @@ -12,7 +12,7 @@ class UserSplitName extends AbstractMigration // Rename "name" to "firstname" and add "lastname". $this->table('user') ->renameColumn('name', 'firstname') - ->addColumn('lastname','string', [ + ->addColumn('lastname', 'string', [ 'length' => 128, 'after' => 'firstname', 'null' => true @@ -20,7 +20,7 @@ class UserSplitName extends AbstractMigration ->save(); // Update row data, moving everything after first space to from lastname. - foreach($this->fetchAll("SELECT `id`,`firstname` FROM `user`") as $row) { + foreach ($this->fetchAll("SELECT `id`,`firstname` FROM `user`") as $row) { $builder = $this->getQueryBuilder()->update('user') ->where(['id' => $row['id']]); @@ -31,7 +31,7 @@ class UserSplitName extends AbstractMigration $pos = strpos($firstname, ' '); if ($pos !== false) { // Set everything after the first space to lastname. - $builder->set('lastname', substr($firstname, $pos+1)); + $builder->set('lastname', substr($firstname, $pos + 1)); // Remove everything after first space from firstname. $firstname = substr($firstname, 0, $pos); diff --git a/app/migrations/20181003134001_user_type.php b/app/migrations/20181003134001_user_type.php index 20f02b1..2825ea1 100644 --- a/app/migrations/20181003134001_user_type.php +++ b/app/migrations/20181003134001_user_type.php @@ -11,7 +11,7 @@ class UserType extends AbstractMigration ->addColumn('type', 'enum', [ 'null' => false, 'default' => 'user', - 'values' => [ 'user', 'admin' ], + 'values' => ['user', 'admin'], 'after' => 'regdate' ]) ->save(); diff --git a/app/models/Data/Base.php b/app/models/Data/Base.php index ed81300..23186b6 100644 --- a/app/models/Data/Base.php +++ b/app/models/Data/Base.php @@ -18,7 +18,7 @@ class Base extends Model * @param boolean $allFields * @return bool */ - public function hasChanged($fieldName = null, bool $allFields = false) : bool + public function hasChanged($fieldName = null, bool $allFields = false): bool { return $this->hasSnapshotData() === false || parent::hasChanged($fieldName, $allFields); diff --git a/app/models/Data/Callback.php b/app/models/Data/Callback.php index d28c44d..a0e9825 100644 --- a/app/models/Data/Callback.php +++ b/app/models/Data/Callback.php @@ -216,8 +216,8 @@ class Callback extends Model */ public function initialize() { - // Set table name mapped in the model. - $this->setSource('callback'); + // Set table name mapped in the model. + $this->setSource('callback'); $this->useDynamicUpdate(true); diff --git a/app/models/Data/Request.php b/app/models/Data/Request.php index 0d2c279..67d379d 100644 --- a/app/models/Data/Request.php +++ b/app/models/Data/Request.php @@ -53,7 +53,7 @@ class Request extends Model */ public function setHeaders($headers) { - foreach($headers as $k => $v) { + foreach ($headers as $k => $v) { if (strlen($v) < 1) { unset($headers[$k]); diff --git a/app/models/Data/RequestMeta.php b/app/models/Data/RequestMeta.php index 73678e8..0c4fffe 100644 --- a/app/models/Data/RequestMeta.php +++ b/app/models/Data/RequestMeta.php @@ -161,7 +161,7 @@ class RequestMeta extends Model $query = (string) parse_url($this->getUri(), PHP_URL_QUERY); $ret = array(); - foreach(explode('&', $query) as $v) { + foreach (explode('&', $query) as $v) { @list($k, $v) = explode('=', $v, 2); if (strlen($k) > 0) { $ret[$k] = $v; @@ -211,7 +211,7 @@ class RequestMeta extends Model { $headers = $this->getHeaders(); - foreach($headers as $k => $v) { + foreach ($headers as $k => $v) { if ($k == 'Content-Length') { return $v; @@ -224,7 +224,7 @@ class RequestMeta extends Model { $headers = $this->getHeaders(); - foreach($headers as $k => $v) { + foreach ($headers as $k => $v) { if ($k == 'Content-Type') { return substr($v, strrpos($v, '/') + 1); diff --git a/app/models/Data/User.php b/app/models/Data/User.php index 7bb2cbb..a4475e6 100644 --- a/app/models/Data/User.php +++ b/app/models/Data/User.php @@ -61,7 +61,7 @@ class User extends Base 'message' => 'The username already exists.' ]), 'email' => new CallbackValidator([ - 'callback' => function() { + 'callback' => function () { return $this->findFirstByEmail($this->getEmail()) === false; }, 'message' => 'The email address already exists.' @@ -69,7 +69,7 @@ class User extends Base ]; $validation = new Validation(); - foreach($rules as $field => $validator) { + foreach ($rules as $field => $validator) { // Only validate changed fields. if ($this->hasChanged($field)) { @@ -414,7 +414,7 @@ class User extends Base { return self::findFirst([ "(email = :v: OR username = :v:) AND status != :s:", - "bind" => [ 'v' => $value, 's' => self::STATUS_DELETED ] + "bind" => ['v' => $value, 's' => self::STATUS_DELETED] ]); } @@ -422,7 +422,7 @@ class User extends Base { return self::findFirst([ "email = :email: AND status != :s:", - "bind" => [ 'email' => $email, 's' => self::STATUS_DELETED ] + "bind" => ['email' => $email, 's' => self::STATUS_DELETED] ]); } @@ -430,7 +430,7 @@ class User extends Base { return self::findFirst([ "username = :username: AND status != :s:", - "bind" => [ 'username' => $username, 's' => self::STATUS_DELETED ] + "bind" => ['username' => $username, 's' => self::STATUS_DELETED] ]); } @@ -440,7 +440,7 @@ class User extends Base return self::findFirst([ "{$column}_id = :id: AND status != :s:", - "bind" => [ 'id' => $oauth->getId(), 's' => self::STATUS_DELETED ] + "bind" => ['id' => $oauth->getId(), 's' => self::STATUS_DELETED] ]); } diff --git a/app/models/Data/UserActivation.php b/app/models/Data/UserActivation.php index 1703298..20ffb5f 100644 --- a/app/models/Data/UserActivation.php +++ b/app/models/Data/UserActivation.php @@ -79,7 +79,7 @@ class UserActivation extends Base * @param int $id * @return PasswordLink */ - public function setId(int $id) : UserActivation + public function setId(int $id): UserActivation { $this->id = $id; return $this; @@ -97,7 +97,7 @@ class UserActivation extends Base * @param string $public_id * @return UserActivation */ - public function setActivationKey(string $key) : UserActivation + public function setActivationKey(string $key): UserActivation { $this->activation_key = $key; return $this; @@ -115,7 +115,7 @@ class UserActivation extends Base * @param int $user_id * @return UserActivation */ - public function setUserId(int $user_id) : UserActivation + public function setUserId(int $user_id): UserActivation { $this->user_id = $user_id; return $this; @@ -133,7 +133,7 @@ class UserActivation extends Base * @param string $password * @return UserActivation */ - public function setPassword(string $password) : UserActivation + public function setPassword(string $password): UserActivation { $this->password = $password; return $this; @@ -144,7 +144,7 @@ class UserActivation extends Base * * @return bool */ - public function isUsed() : bool + public function isUsed(): bool { return (bool) $this->used; } @@ -154,7 +154,7 @@ class UserActivation extends Base * * @return bool */ - public function isValid() : bool + public function isValid(): bool { // Used links are not valid. if ($this->isUsed()) { @@ -175,9 +175,9 @@ class UserActivation extends Base public function beforeCreate() { // Creating a new link automatically removes old ones. - $links = self::find(["user_id = ?0", 'bind' => [ $this->user_id ]]); + $links = self::find(["user_id = ?0", 'bind' => [$this->user_id]]); - foreach($links as $link) { + foreach ($links as $link) { $link->delete(); } } diff --git a/app/modules/Base.php b/app/modules/Base.php index 2e2b5a3..21ab532 100644 --- a/app/modules/Base.php +++ b/app/modules/Base.php @@ -39,9 +39,8 @@ abstract class Base implements ModuleDefinitionInterface $dispatcher->setDefaultNamespace($this->_controllerNamespace); $di->get('view')->setViewsDir(array_merge( - [ $this->_viewDir ], + [$this->_viewDir], (array) $di->get('view')->getViewsDir() )); } } - From 6439a83edbdb9f74de4607bf9173e4a638ae6e33 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 17:34:18 +0200 Subject: [PATCH 25/32] app/listeners/ActivityLog.php: Adding onImpersonate listener --- app/listeners/ActivityLog.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/listeners/ActivityLog.php b/app/listeners/ActivityLog.php index 906b3be..4f4787c 100644 --- a/app/listeners/ActivityLog.php +++ b/app/listeners/ActivityLog.php @@ -23,6 +23,19 @@ class ActivityLog extends Injectable $this->_log($auth->getUser(), sprintf("Logged in (%s)", $type)); } + /** + * On Impersonate event. + * + * @param Event $event + * @param Auth $auth + * @param User $user The user Impersonating the user in $auth + */ + public function onImpersonate(Event $event, Auth $auth, User $user) + { + $imp = $auth->getUser(); + $this->_log($user, sprintf("Impersonated user (%s:%s)", $imp->getId(), $imp->getUsername())); + } + /** * @param Event $event * @param User $auth From 69fd7a6e193e6132c9dc88d45ef5c44b8f92957d Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 17:34:59 +0200 Subject: [PATCH 26/32] app/library/Auth.php: adding impersonate() and impersonateClear() methods --- app/library/Auth.php | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/app/library/Auth.php b/app/library/Auth.php index 81750da..33a46f4 100644 --- a/app/library/Auth.php +++ b/app/library/Auth.php @@ -10,6 +10,7 @@ use App\Model\Data\User, class Auth extends Injectable { const SESSION_KEY = 'auth'; + const IMPERSONATEOR_ID = 'auth.impersonateor'; /** * Login using email/user + password combination. @@ -86,6 +87,34 @@ class Auth extends Injectable $this->eventsManager->fire('auth:onLogin', $this, 'System'); } + /** + * Impersonate a user + * + * @param User $user + */ + public function impersonate(User $user) + { + $current = $this->getIdentity(); + if ($current === null) { + throw new \InvalidArgumentException("Need to be authenticated to be able to impersonate someone"); + } + + if ($current->getId() === $user->getId()) { + // Same user + throw new \DomainException("Can't impersonate yourself"); + } + + $this->session->set(self::IMPERSONATEOR_ID, $current->getId()); + $this->setIdentity($user->getId()); + $this->eventsManager->fire('auth:onImpersonate', $this, $current); + } + + public function impersonateClear($imp_id) + { + $this->session->remove(self::IMPERSONATEOR_ID); + $this->session->set(self::SESSION_KEY, $imp_id); + } + /** * @param $identity * @return Auth @@ -135,7 +164,12 @@ class Auth extends Injectable */ public function clearIdentity() { - $this->session->remove(self::SESSION_KEY); + $imp_id = $this->session->get(self::IMPERSONATEOR_ID); + if ($imp_id !== null) { + $this->impersonateClear($imp_id); + } else { + $this->session->remove(self::SESSION_KEY); + } return $this; } } From 4ac770f7339491e5a28708843b75bef6a6390bdb Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 17:49:36 +0200 Subject: [PATCH 27/32] app/controllers/backend/UserController.php: adding impersonateAction() --- app/controllers/backend/UserController.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index 8737728..bad595e 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -113,4 +113,17 @@ class UserController extends \Phalcon\Mvc\Controller } $this->response->redirect('/admin'); } + + public function impersonateAction($id) + { + $user = User::findFirstById($id); + + try { + $this->auth->impersonate($user); + $this->response->redirect('/'); + } catch (\Exception $ex) { + $this->flash->error($ex->getMessage()); + $this->response->redirect('/admin'); + } + } } From 24edb5cb5986944154441e1380e437b65886ac14 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 17:50:21 +0200 Subject: [PATCH 28/32] app/config/routes.yml: add impersonate route. --- app/config/routes.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/config/routes.yml b/app/config/routes.yml index 8974a32..2e905c6 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -73,6 +73,9 @@ router: backend-user-edit: pattern: '/admin/user/{id:([0-9]+)}' path: backend::user::edit + backend-user-impersonate: + pattern: '/admin/impersonate/{id:([0-9]+)}' + path: backend::user::impersonate backend-user-activation-email: pattern: '/admin/user/{id:([0-9]+)}/activation' path: backend::user::activation-email From 0634db6d0c92e5f88794fc12b4926f96802d5910 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 17:50:36 +0200 Subject: [PATCH 29/32] app/views/backend/user/index.volt: Add icon link to impersonate users --- app/views/backend/user/index.volt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/views/backend/user/index.volt b/app/views/backend/user/index.volt index 821fca9..94b5241 100644 --- a/app/views/backend/user/index.volt +++ b/app/views/backend/user/index.volt @@ -20,6 +20,7 @@ Email Type Status +   @@ -37,6 +38,11 @@ {{ item.email }} {{ item.type | capitalize }} {{ item.status }} + + + {{ icon('solid/user-secret') }} + + {% endfor %} From 6dc1d0fb872c644d856b6a0243dbfa7ca3cd404c Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 18:03:23 +0200 Subject: [PATCH 30/32] app/library/Auth.php: Fix typo. --- app/library/Auth.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/library/Auth.php b/app/library/Auth.php index 33a46f4..7d343cb 100644 --- a/app/library/Auth.php +++ b/app/library/Auth.php @@ -10,7 +10,7 @@ use App\Model\Data\User, class Auth extends Injectable { const SESSION_KEY = 'auth'; - const IMPERSONATEOR_ID = 'auth.impersonateor'; + const IMPERSONATOR_ID = 'auth.impersonator'; /** * Login using email/user + password combination. @@ -104,14 +104,14 @@ class Auth extends Injectable throw new \DomainException("Can't impersonate yourself"); } - $this->session->set(self::IMPERSONATEOR_ID, $current->getId()); + $this->session->set(self::IMPERSONATOR_ID, $current->getId()); $this->setIdentity($user->getId()); $this->eventsManager->fire('auth:onImpersonate', $this, $current); } public function impersonateClear($imp_id) { - $this->session->remove(self::IMPERSONATEOR_ID); + $this->session->remove(self::IMPERSONATOR_ID); $this->session->set(self::SESSION_KEY, $imp_id); } @@ -164,7 +164,7 @@ class Auth extends Injectable */ public function clearIdentity() { - $imp_id = $this->session->get(self::IMPERSONATEOR_ID); + $imp_id = $this->session->get(self::IMPERSONATOR_ID); if ($imp_id !== null) { $this->impersonateClear($imp_id); } else { From bf940f95231d82eb72c2ed0dee8014c3bb254f6a Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 18:04:35 +0200 Subject: [PATCH 31/32] app/library/Auth.php: Adding getImpersonator() --- app/library/Auth.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/library/Auth.php b/app/library/Auth.php index 7d343cb..80ea7bd 100644 --- a/app/library/Auth.php +++ b/app/library/Auth.php @@ -87,6 +87,12 @@ class Auth extends Injectable $this->eventsManager->fire('auth:onLogin', $this, 'System'); } + public function getImpersonator() + { + $id = $this->session->get(self::IMPERSONATOR_ID); + return $id !== null ? User::findFirst($id) : null; + } + /** * Impersonate a user * From a757e9527799e197c72577c52af1555418c44a75 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 30 Apr 2023 18:05:27 +0200 Subject: [PATCH 32/32] app/views/_common/_components/navigation.volt: show both users if the user are impersonating another user. --- app/views/_common/_components/navigation.volt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/_common/_components/navigation.volt b/app/views/_common/_components/navigation.volt index eaf3fd7..9b11888 100644 --- a/app/views/_common/_components/navigation.volt +++ b/app/views/_common/_components/navigation.volt @@ -12,6 +12,8 @@ data-bs-toggle="dropdown" role="button" aria-expanded="false"> {{ icon('solid/user') }} {{ auth.getUser().username }} + {% set imp = auth.getImpersonator() %} + {% if imp %}( {{ icon('solid/user-secret') }} {{ imp.username }} ){% endif %}