diff --git a/app/locales/en_GB/LC_MESSAGES/messages.mo b/app/locales/en_GB/LC_MESSAGES/messages.mo
index d94f33fc..995903bd 100644
Binary files a/app/locales/en_GB/LC_MESSAGES/messages.mo and b/app/locales/en_GB/LC_MESSAGES/messages.mo differ
diff --git a/app/locales/en_GB/LC_MESSAGES/messages.po b/app/locales/en_GB/LC_MESSAGES/messages.po
index 2c778eb0..d4a57c47 100644
--- a/app/locales/en_GB/LC_MESSAGES/messages.po
+++ b/app/locales/en_GB/LC_MESSAGES/messages.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: sysPass\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-10-12 00:42+0200\n"
-"PO-Revision-Date: 2018-10-12 00:42+0200\n"
+"POT-Creation-Date: 2018-10-15 02:52+0200\n"
+"PO-Revision-Date: 2018-10-15 02:55+0200\n"
"Last-Translator: nuxsmin \n"
"Language-Team: nuxsmin@syspass.org\n"
"Language: en_GB\n"
@@ -25,12 +25,12 @@ msgstr ""
"X-Poedit-SearchPath-1: ../../../../lib\n"
"X-Poedit-SearchPath-2: ../../../config\n"
-#: ../../../../lib/SP/Bootstrap.php:267
+#: ../../../../lib/SP/Bootstrap.php:278
#, php-format
msgid "Versión de PHP requerida >= %s <= %s"
msgstr "Required PHP version >= %s <= %s"
-#: ../../../../lib/SP/Bootstrap.php:269
+#: ../../../../lib/SP/Bootstrap.php:280
msgid ""
"Actualice la versión de PHP para que la aplicación funcione correctamente"
msgstr "Please update the PHP version to run sysPass"
@@ -53,7 +53,7 @@ msgid "Actual: %s - Necesario: 750"
msgstr "Current: %s - Needed: 750"
#: ../../../../lib/SP/Core/Acl/AccountPermissionException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:132
+#: ../../../../lib/SP/Util/ErrorUtil.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:96
msgid "No tiene permisos para acceder a esta cuenta"
msgstr "You don't have permission to access to this account"
@@ -61,12 +61,12 @@ msgstr "You don't have permission to access to this account"
#: ../../../../lib/SP/Core/Acl/AccountPermissionException.php:45
#: ../../../../lib/SP/Core/Acl/UnauthorizedActionException.php:46
#: ../../../../lib/SP/Core/Acl/UnauthorizedPageException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:129
-#: ../../../../lib/SP/Util/ErrorUtil.php:133
-#: ../../../../lib/SP/Util/ErrorUtil.php:137
-#: ../../../../lib/SP/Util/ErrorUtil.php:141
-#: ../../../../lib/SP/Util/ErrorUtil.php:149
-#: ../../../../lib/SP/Util/ErrorUtil.php:156
+#: ../../../../lib/SP/Util/ErrorUtil.php:139
+#: ../../../../lib/SP/Util/ErrorUtil.php:143
+#: ../../../../lib/SP/Util/ErrorUtil.php:147
+#: ../../../../lib/SP/Util/ErrorUtil.php:151
+#: ../../../../lib/SP/Util/ErrorUtil.php:159
+#: ../../../../lib/SP/Util/ErrorUtil.php:166
#: ../../../modules/web/Controllers/ErrorController.php:124
#: ../../../modules/web/Controllers/UserPassResetController.php:94
#: ../../../modules/web/themes/material-blue/views/upgrade/index.inc:13
@@ -75,7 +75,7 @@ msgstr "Please contact to the administrator"
# Not available
#: ../../../../lib/SP/Core/Acl/Acl.php:294
-#: ../../../../lib/SP/Services/Auth/LoginService.php:600
+#: ../../../../lib/SP/Services/Auth/LoginService.php:604
msgid "N/D"
msgstr "N/A"
@@ -96,24 +96,24 @@ msgstr "Action"
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapMsAds.php:155
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapStd.php:110
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapStd.php:142
-#: ../../../../lib/SP/Services/Auth/LoginService.php:217
-#: ../../../../lib/SP/Services/Auth/LoginService.php:235
-#: ../../../../lib/SP/Services/Auth/LoginService.php:386
-#: ../../../../lib/SP/Services/Auth/LoginService.php:453
-#: ../../../../lib/SP/Services/Auth/LoginService.php:561
-#: ../../../../lib/SP/Services/Auth/LoginService.php:604
+#: ../../../../lib/SP/Services/Auth/LoginService.php:220
+#: ../../../../lib/SP/Services/Auth/LoginService.php:238
+#: ../../../../lib/SP/Services/Auth/LoginService.php:390
+#: ../../../../lib/SP/Services/Auth/LoginService.php:457
+#: ../../../../lib/SP/Services/Auth/LoginService.php:565
+#: ../../../../lib/SP/Services/Auth/LoginService.php:608
#: ../../../../lib/SP/Services/Ldap/LdapImportService.php:238
#: ../../../modules/web/Controllers/Helpers/Account/AccountSearchHelper.php:253
#: ../../../modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php:106
#: ../../../modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php:107
#: ../../../modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php:111
#: ../../../modules/web/Controllers/Helpers/Grid/TrackGrid.php:105
-#: ../../../modules/web/Controllers/LoginController.php:102
+#: ../../../modules/web/Controllers/LoginController.php:120
#: ../../../modules/web/Controllers/UserController.php:278
#: ../../../modules/web/Controllers/UserController.php:312
#: ../../../modules/web/Controllers/UserController.php:373
#: ../../../modules/web/Controllers/UserController.php:412
-#: ../../../modules/web/Controllers/UserPassResetController.php:187
+#: ../../../modules/web/Controllers/UserPassResetController.php:190
#: ../../../modules/web/themes/material-blue/views/account/account-editpass.inc:55
#: ../../../modules/web/themes/material-blue/views/account/account-editpass.inc:61
#: ../../../modules/web/themes/material-blue/views/account/account-history.inc:91
@@ -151,7 +151,7 @@ msgid "Acción no encontrada"
msgstr "Action not found"
#: ../../../../lib/SP/Core/Acl/UnauthorizedActionException.php:46
-#: ../../../../lib/SP/Util/ErrorUtil.php:140
+#: ../../../../lib/SP/Util/ErrorUtil.php:150
#: ../../../modules/web/Controllers/AccountFileController.php:261
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:59
#: ../../../modules/web/Controllers/AccountManagerController.php:77
@@ -200,8 +200,8 @@ msgstr "Action not found"
#: ../../../modules/web/Controllers/NotificationController.php:288
#: ../../../modules/web/Controllers/NotificationController.php:315
#: ../../../modules/web/Controllers/NotificationController.php:348
-#: ../../../modules/web/Controllers/PluginController.php:98
-#: ../../../modules/web/Controllers/PluginController.php:117
+#: ../../../modules/web/Controllers/PluginController.php:103
+#: ../../../modules/web/Controllers/PluginController.php:122
#: ../../../modules/web/Controllers/PublicLinkController.php:71
#: ../../../modules/web/Controllers/PublicLinkController.php:105
#: ../../../modules/web/Controllers/PublicLinkController.php:167
@@ -244,7 +244,7 @@ msgid "No tiene permisos para realizar esta operación"
msgstr "You don't have permission to do this operation"
#: ../../../../lib/SP/Core/Acl/UnauthorizedPageException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:136
+#: ../../../../lib/SP/Util/ErrorUtil.php:146
msgid "No tiene permisos para acceder a esta página"
msgstr "You don't have permission to access this page"
@@ -280,14 +280,14 @@ msgstr "Session cannot be initialized"
#: ../../../../lib/SP/Services/Account/AccountService.php:227
#: ../../../../lib/SP/Services/Account/AccountService.php:232
#: ../../../../lib/SP/Services/Api/ApiService.php:129
-#: ../../../../lib/SP/Services/Api/ApiService.php:227
-#: ../../../../lib/SP/Services/Api/ApiService.php:235
-#: ../../../../lib/SP/Services/Auth/LoginService.php:187
-#: ../../../../lib/SP/Services/Auth/LoginService.php:351
-#: ../../../../lib/SP/Services/Auth/LoginService.php:500
-#: ../../../../lib/SP/Services/Auth/LoginService.php:505
-#: ../../../../lib/SP/Services/Auth/LoginService.php:537
-#: ../../../../lib/SP/Services/Auth/LoginService.php:644
+#: ../../../../lib/SP/Services/Api/ApiService.php:229
+#: ../../../../lib/SP/Services/Api/ApiService.php:237
+#: ../../../../lib/SP/Services/Auth/LoginService.php:190
+#: ../../../../lib/SP/Services/Auth/LoginService.php:354
+#: ../../../../lib/SP/Services/Auth/LoginService.php:504
+#: ../../../../lib/SP/Services/Auth/LoginService.php:509
+#: ../../../../lib/SP/Services/Auth/LoginService.php:541
+#: ../../../../lib/SP/Services/Auth/LoginService.php:648
#: ../../../../lib/SP/Services/AuthToken/AuthTokenService.php:311
#: ../../../../lib/SP/Services/CustomField/CustomFieldService.php:203
#: ../../../../lib/SP/Services/Export/XmlVerifyService.php:108
@@ -306,7 +306,7 @@ msgstr "Crypto module cannot be loaded"
msgid "Error al generar datos cifrados"
msgstr "Error while creating the encrypted data"
-#: ../../../../lib/SP/Core/Events/Event.php:56
+#: ../../../../lib/SP/Core/Events/Event.php:57
msgid "Es necesario un objeto"
msgstr "An object is needed"
@@ -320,17 +320,17 @@ msgstr "Invalid icons class"
#: ../../../../lib/SP/DataModel/PublicLinkListData.php:88
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapConnection.php:190
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "ON"
msgstr "ON"
#: ../../../../lib/SP/DataModel/PublicLinkListData.php:88
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "OFF"
msgstr "OFF"
#: ../../../../lib/SP/Html/DataGrid/DataGridBase.php:303
-#: ../../../../lib/SP/Mvc/View/Template.php:122
+#: ../../../../lib/SP/Mvc/View/Template.php:126
#, php-format
msgid "No es posible obtener la plantilla \"%s\" : %s"
msgstr "Unable to retrieve the \"%s\" template: %s"
@@ -352,11 +352,11 @@ msgstr "Encoding error"
msgid "Respuesta XML-RPC inválida"
msgstr "Invalid XML-RPC response"
-#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:64
+#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:71
msgid "La sesión no se ha iniciado o ha caducado"
msgstr "Session not started or timed out"
-#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:114
+#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:124
msgid "Acción Inválida"
msgstr "Invalid Action"
@@ -398,41 +398,69 @@ msgstr "Invalid filter type"
msgid "Tipo de objeto incorrecto"
msgstr "Wrong object type"
-#: ../../../../lib/SP/Mvc/View/Template.php:274
-#: ../../../../lib/SP/Mvc/View/Template.php:276
+#: ../../../../lib/SP/Mvc/View/Template.php:278
+#: ../../../../lib/SP/Mvc/View/Template.php:280
#, php-format
msgid "No es posible obtener la variable \"%s\""
msgstr "Unable to retrieve the \"%s\" variable"
-#: ../../../../lib/SP/Mvc/View/Template.php:322
-#: ../../../../lib/SP/Mvc/View/Template.php:324
+#: ../../../../lib/SP/Mvc/View/Template.php:326
+#: ../../../../lib/SP/Mvc/View/Template.php:328
#, php-format
msgid "No es posible destruir la variable \"%s\""
msgstr "Unable to unset the \"%s\" variable"
-#: ../../../../lib/SP/Mvc/View/Template.php:341
+#: ../../../../lib/SP/Mvc/View/Template.php:345
msgid "La plantilla no contiene archivos"
msgstr "Template does not contain files"
-#: ../../../../lib/SP/Plugin/PluginManager.php:113
-#: ../../../../lib/SP/Plugin/PluginManager.php:256
+#: ../../../../lib/SP/Plugin/PluginManager.php:170
+#, php-format
+msgid "Versión de plugin no compatible (%s)"
+msgstr "Plugin version not compatible (%s)"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:192
#, php-format
msgid "No es posible cargar el plugin \"%s\""
msgstr "Unable to load the \"%s\" plugin"
+#: ../../../../lib/SP/Plugin/PluginManager.php:194
+#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:101
+msgid "Plugin"
+msgstr "Plugin"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:219
+#: ../../../../lib/SP/Plugin/PluginManager.php:339
+#: ../../../modules/web/Controllers/PluginController.php:213
+#: ../../../modules/web/Controllers/PluginController.php:216
+msgid "Plugin deshabilitado"
+msgstr "Plugin disabled"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:254
+msgid "Plugin disponible"
+msgstr "Plugin available"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:264
+msgid "Plugin no disponible"
+msgstr "Plugin unavailable"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:294
+msgid "Plugin cargado"
+msgstr "Plugin loaded"
+
#. (itstool) path: action/text
-#: ../../../../lib/SP/Plugin/PluginManager.php:245
+#: ../../../../lib/SP/Plugin/PluginManager.php:319
#: ../../../config/actions.xml:535
msgid "Nuevo Plugin"
msgstr "New Plugin"
-#: ../../../../lib/SP/Plugin/PluginManager.php:246
+#: ../../../../lib/SP/Plugin/PluginManager.php:320
#: ../../../modules/api/Controllers/AccountController.php:71
#: ../../../modules/api/Controllers/AccountController.php:103
#: ../../../modules/api/Controllers/AccountController.php:139
-#: ../../../modules/api/Controllers/AccountController.php:185
-#: ../../../modules/api/Controllers/AccountController.php:235
-#: ../../../modules/api/Controllers/AccountController.php:310
+#: ../../../modules/api/Controllers/AccountController.php:189
+#: ../../../modules/api/Controllers/AccountController.php:240
+#: ../../../modules/api/Controllers/AccountController.php:315
#: ../../../modules/api/Controllers/CategoryController.php:63
#: ../../../modules/api/Controllers/CategoryController.php:92
#: ../../../modules/api/Controllers/CategoryController.php:122
@@ -490,7 +518,7 @@ msgid "Método ya inicializado"
msgstr "Method already initialized"
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:119
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:125
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:126
msgid "Error al buscar RDN de grupo"
msgstr "Error while searching the group RDN"
@@ -518,13 +546,13 @@ msgstr "Error while searching the group RDN"
msgid "Grupo"
msgstr "Group"
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:200
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:204
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:205
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:210
msgid "Error al localizar el usuario en LDAP"
msgstr "Error while searching the user on LDAP"
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:249
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:254
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:259
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:265
msgid "Error al buscar objetos en DN base"
msgstr "Error while searching objects in base DN"
@@ -594,7 +622,7 @@ msgid "No es posible inicializar"
msgstr "Unable to initialize"
#: ../../../../lib/SP/Providers/Notification/NotificationHandler.php:124
-#: ../../../modules/web/Controllers/AccountController.php:926
+#: ../../../modules/web/Controllers/AccountController.php:925
msgid "Solicitud"
msgstr "Request"
@@ -1121,7 +1149,7 @@ msgstr "The account doesn't exist"
#: ../../../../lib/SP/Services/Api/ApiRequest.php:79
#: ../../../../lib/SP/Services/Api/ApiRequest.php:113
-#: ../../../../lib/SP/Services/Api/ApiService.php:229
+#: ../../../../lib/SP/Services/Api/ApiService.php:231
msgid "Datos inválidos"
msgstr "Invalid data"
@@ -1130,7 +1158,7 @@ msgid "Fomato incorrecto"
msgstr "Invalid format"
#: ../../../../lib/SP/Services/Api/ApiService.php:96
-#: ../../../../lib/SP/Services/Auth/LoginService.php:137
+#: ../../../../lib/SP/Services/Auth/LoginService.php:138
#: ../../../../lib/SP/Services/UserPassRecover/UserPassRecoverService.php:103
#: ../../../modules/web/Controllers/UserPassResetController.php:124
msgid "Intentos excedidos"
@@ -1145,54 +1173,54 @@ msgstr "Wrong parameters"
msgid "Acceso no permitido"
msgstr "Unauthorized access"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:157
-#: ../../../../lib/SP/Services/Auth/LoginService.php:456
-#: ../../../../lib/SP/Services/Auth/LoginService.php:463
-#: ../../../../lib/SP/Services/Auth/LoginService.php:571
-#: ../../../../lib/SP/Services/Auth/LoginService.php:576
-#: ../../../../lib/SP/Services/Auth/LoginService.php:615
-#: ../../../../lib/SP/Services/Auth/LoginService.php:620
+#: ../../../../lib/SP/Services/Auth/LoginService.php:160
+#: ../../../../lib/SP/Services/Auth/LoginService.php:460
+#: ../../../../lib/SP/Services/Auth/LoginService.php:467
+#: ../../../../lib/SP/Services/Auth/LoginService.php:575
+#: ../../../../lib/SP/Services/Auth/LoginService.php:580
+#: ../../../../lib/SP/Services/Auth/LoginService.php:619
+#: ../../../../lib/SP/Services/Auth/LoginService.php:624
msgid "Login incorrecto"
msgstr "Wrong login"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:216
-#: ../../../../lib/SP/Services/Auth/LoginService.php:223
+#: ../../../../lib/SP/Services/Auth/LoginService.php:219
+#: ../../../../lib/SP/Services/Auth/LoginService.php:226
msgid "Usuario deshabilitado"
msgstr "User disabled"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:270
+#: ../../../../lib/SP/Services/Auth/LoginService.php:273
msgid "Usando clave temporal"
msgstr "Using temporary password"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:282
-#: ../../../../lib/SP/Services/Auth/LoginService.php:288
-#: ../../../../lib/SP/Services/Auth/LoginService.php:306
-#: ../../../../lib/SP/Services/Auth/LoginService.php:312
+#: ../../../../lib/SP/Services/Auth/LoginService.php:285
+#: ../../../../lib/SP/Services/Auth/LoginService.php:291
+#: ../../../../lib/SP/Services/Auth/LoginService.php:309
+#: ../../../../lib/SP/Services/Auth/LoginService.php:315
msgid "Clave maestra incorrecta"
msgstr "Wrong master password"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:297
-#: ../../../../lib/SP/Services/Auth/LoginService.php:321
+#: ../../../../lib/SP/Services/Auth/LoginService.php:300
+#: ../../../../lib/SP/Services/Auth/LoginService.php:324
#: ../../../../lib/SP/Services/User/UpdatedMasterPassException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:144
+#: ../../../../lib/SP/Util/ErrorUtil.php:154
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:68
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:116
msgid "Clave maestra actualizada"
msgstr "Master password updated"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:327
+#: ../../../../lib/SP/Services/Auth/LoginService.php:330
msgid "Es necesaria su clave anterior"
msgstr "Your previous password is needed"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:339
+#: ../../../../lib/SP/Services/Auth/LoginService.php:342
msgid "La clave maestra no ha sido guardada o es incorrecta"
msgstr "The Master Password either is not saved or is wrong"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:451
-#: ../../../../lib/SP/Services/Auth/LoginService.php:514
-#: ../../../../lib/SP/Services/Auth/LoginService.php:560
-#: ../../../../lib/SP/Services/Auth/LoginService.php:603
+#: ../../../../lib/SP/Services/Auth/LoginService.php:455
+#: ../../../../lib/SP/Services/Auth/LoginService.php:518
+#: ../../../../lib/SP/Services/Auth/LoginService.php:564
+#: ../../../../lib/SP/Services/Auth/LoginService.php:607
#: ../../../modules/web/Controllers/AccountFileController.php:235
#: ../../../modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php:108
#: ../../../modules/web/Controllers/Helpers/Grid/FileGrid.php:108
@@ -1207,22 +1235,22 @@ msgstr "The Master Password either is not saved or is wrong"
msgid "Tipo"
msgstr "Type"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:452
-#: ../../../../lib/SP/Services/Auth/LoginService.php:515
+#: ../../../../lib/SP/Services/Auth/LoginService.php:456
+#: ../../../../lib/SP/Services/Auth/LoginService.php:519
msgid "Servidor LDAP"
msgstr "LDAP Server"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:471
-#: ../../../../lib/SP/Services/Auth/LoginService.php:476
+#: ../../../../lib/SP/Services/Auth/LoginService.php:475
+#: ../../../../lib/SP/Services/Auth/LoginService.php:480
msgid "Cuenta expirada"
msgstr "Account expired"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:484
-#: ../../../../lib/SP/Services/Auth/LoginService.php:489
+#: ../../../../lib/SP/Services/Auth/LoginService.php:488
+#: ../../../../lib/SP/Services/Auth/LoginService.php:493
msgid "El usuario no tiene grupos asociados"
msgstr "The user has no associated groups"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:605
+#: ../../../../lib/SP/Services/Auth/LoginService.php:609
#: ../../../modules/web/themes/material-blue/views/config/general-auth.inc:10
msgid "Autentificación"
msgstr "Authentication"
@@ -1503,16 +1531,16 @@ msgstr "Account imported"
#: ../../../modules/api/Controllers/AccountController.php:72
#: ../../../modules/api/Controllers/AccountController.php:104
#: ../../../modules/api/Controllers/AccountController.php:140
-#: ../../../modules/api/Controllers/AccountController.php:186
-#: ../../../modules/api/Controllers/AccountController.php:236
-#: ../../../modules/api/Controllers/AccountController.php:311
-#: ../../../modules/web/Controllers/AccountController.php:225
-#: ../../../modules/web/Controllers/AccountController.php:720
-#: ../../../modules/web/Controllers/AccountController.php:765
-#: ../../../modules/web/Controllers/AccountController.php:806
-#: ../../../modules/web/Controllers/AccountController.php:845
-#: ../../../modules/web/Controllers/AccountController.php:895
-#: ../../../modules/web/Controllers/AccountController.php:929
+#: ../../../modules/api/Controllers/AccountController.php:190
+#: ../../../modules/api/Controllers/AccountController.php:241
+#: ../../../modules/api/Controllers/AccountController.php:316
+#: ../../../modules/web/Controllers/AccountController.php:224
+#: ../../../modules/web/Controllers/AccountController.php:719
+#: ../../../modules/web/Controllers/AccountController.php:764
+#: ../../../modules/web/Controllers/AccountController.php:805
+#: ../../../modules/web/Controllers/AccountController.php:844
+#: ../../../modules/web/Controllers/AccountController.php:894
+#: ../../../modules/web/Controllers/AccountController.php:928
#: ../../../modules/web/Controllers/AccountFileController.php:234
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:112
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:147
@@ -2119,7 +2147,7 @@ msgid "Enlace"
msgstr "Link"
#: ../../../../lib/SP/Services/User/UpdatedMasterPassException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:145
+#: ../../../../lib/SP/Util/ErrorUtil.php:155
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:68
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:116
@@ -2286,12 +2314,12 @@ msgstr "Socket not initialized"
msgid "Error al enviar datos"
msgstr "Error while sending the data"
-#: ../../../../lib/SP/Util/ErrorUtil.php:128
+#: ../../../../lib/SP/Util/ErrorUtil.php:138
msgid "Opción no disponible"
msgstr "Option unavailable"
-#: ../../../../lib/SP/Util/ErrorUtil.php:148
-#: ../../../../lib/SP/Util/ErrorUtil.php:155
+#: ../../../../lib/SP/Util/ErrorUtil.php:158
+#: ../../../../lib/SP/Util/ErrorUtil.php:165
msgid "Se ha producido una excepción"
msgstr "An exception occured"
@@ -2304,40 +2332,40 @@ msgid "Cuenta visualizada"
msgstr "Account displayed"
#: ../../../modules/api/Controllers/AccountController.php:102
-#: ../../../modules/web/Controllers/AccountController.php:554
-#: ../../../modules/web/Controllers/AccountController.php:610
+#: ../../../modules/web/Controllers/AccountController.php:553
+#: ../../../modules/web/Controllers/AccountController.php:609
msgid "Clave visualizada"
msgstr "Password viewed"
#: ../../../modules/api/Controllers/AccountController.php:138
#: ../../../modules/api/Controllers/AccountController.php:144
-#: ../../../modules/web/Controllers/AccountController.php:804
-#: ../../../modules/web/Controllers/AccountController.php:815
+#: ../../../modules/web/Controllers/AccountController.php:803
+#: ../../../modules/web/Controllers/AccountController.php:814
#: ../../../modules/web/Controllers/UserController.php:411
#: ../../../modules/web/Controllers/UserController.php:415
-#: ../../../modules/web/Controllers/UserPassResetController.php:186
-#: ../../../modules/web/Controllers/UserPassResetController.php:190
+#: ../../../modules/web/Controllers/UserPassResetController.php:189
+#: ../../../modules/web/Controllers/UserPassResetController.php:193
msgid "Clave actualizada"
msgstr "Password updated"
-#: ../../../modules/api/Controllers/AccountController.php:184
-#: ../../../modules/api/Controllers/AccountController.php:190
-#: ../../../modules/web/Controllers/AccountController.php:718
-#: ../../../modules/web/Controllers/AccountController.php:729
+#: ../../../modules/api/Controllers/AccountController.php:188
+#: ../../../modules/api/Controllers/AccountController.php:194
+#: ../../../modules/web/Controllers/AccountController.php:717
+#: ../../../modules/web/Controllers/AccountController.php:728
msgid "Cuenta creada"
msgstr "Account added"
-#: ../../../modules/api/Controllers/AccountController.php:234
-#: ../../../modules/api/Controllers/AccountController.php:240
-#: ../../../modules/web/Controllers/AccountController.php:763
-#: ../../../modules/web/Controllers/AccountController.php:774
+#: ../../../modules/api/Controllers/AccountController.php:239
+#: ../../../modules/api/Controllers/AccountController.php:245
+#: ../../../modules/web/Controllers/AccountController.php:762
+#: ../../../modules/web/Controllers/AccountController.php:773
msgid "Cuenta actualizada"
msgstr "Account updated"
-#: ../../../modules/api/Controllers/AccountController.php:309
-#: ../../../modules/api/Controllers/AccountController.php:315
-#: ../../../modules/web/Controllers/AccountController.php:893
-#: ../../../modules/web/Controllers/AccountController.php:898
+#: ../../../modules/api/Controllers/AccountController.php:314
+#: ../../../modules/api/Controllers/AccountController.php:320
+#: ../../../modules/web/Controllers/AccountController.php:892
+#: ../../../modules/web/Controllers/AccountController.php:897
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:110
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:115
#: ../../../modules/web/Controllers/AccountManagerController.php:145
@@ -2709,9 +2737,9 @@ msgstr "Group deleted"
msgid "Es necesario actualizar"
msgstr "Updating needed"
-#: ../../../modules/web/Controllers/AccountController.php:149
-#: ../../../modules/web/Controllers/AccountController.php:204
-#: ../../../modules/web/Controllers/AccountController.php:474
+#: ../../../modules/web/Controllers/AccountController.php:148
+#: ../../../modules/web/Controllers/AccountController.php:203
+#: ../../../modules/web/Controllers/AccountController.php:473
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:60
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:61
#: ../../../modules/web/Controllers/Helpers/Grid/AccountGrid.php:159
@@ -2721,21 +2749,21 @@ msgstr "Updating needed"
msgid "Detalles de Cuenta"
msgstr "Account Details"
-#: ../../../modules/web/Controllers/AccountController.php:223
+#: ../../../modules/web/Controllers/AccountController.php:222
msgid "Enlace visualizado"
msgstr "Link viewed"
-#: ../../../modules/web/Controllers/AccountController.php:224
-#: ../../../modules/web/Controllers/AccountController.php:555
-#: ../../../modules/web/Controllers/AccountController.php:611
-#: ../../../modules/web/Controllers/AccountController.php:650
-#: ../../../modules/web/Controllers/AccountController.php:684
-#: ../../../modules/web/Controllers/AccountController.php:719
-#: ../../../modules/web/Controllers/AccountController.php:764
-#: ../../../modules/web/Controllers/AccountController.php:805
-#: ../../../modules/web/Controllers/AccountController.php:844
-#: ../../../modules/web/Controllers/AccountController.php:894
-#: ../../../modules/web/Controllers/AccountController.php:928
+#: ../../../modules/web/Controllers/AccountController.php:223
+#: ../../../modules/web/Controllers/AccountController.php:554
+#: ../../../modules/web/Controllers/AccountController.php:610
+#: ../../../modules/web/Controllers/AccountController.php:649
+#: ../../../modules/web/Controllers/AccountController.php:683
+#: ../../../modules/web/Controllers/AccountController.php:718
+#: ../../../modules/web/Controllers/AccountController.php:763
+#: ../../../modules/web/Controllers/AccountController.php:804
+#: ../../../modules/web/Controllers/AccountController.php:843
+#: ../../../modules/web/Controllers/AccountController.php:893
+#: ../../../modules/web/Controllers/AccountController.php:927
#: ../../../modules/web/Controllers/AccountFileController.php:233
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:111
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:146
@@ -2749,24 +2777,24 @@ msgstr "Link viewed"
msgid "Cuenta"
msgstr "Account"
-#: ../../../modules/web/Controllers/AccountController.php:226
+#: ../../../modules/web/Controllers/AccountController.php:225
msgid "Agente"
msgstr "Agent"
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "HTTPS"
msgstr "HTTPS"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:256
-#: ../../../modules/web/Controllers/AccountController.php:300
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:278
+#: ../../../modules/web/Controllers/AccountController.php:255
+#: ../../../modules/web/Controllers/AccountController.php:299
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:280
#: ../../../config/actions.xml:157
msgid "Nueva Cuenta"
msgstr "New Account"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:344
+#: ../../../modules/web/Controllers/AccountController.php:343
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:176
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:177
#: ../../../modules/web/themes/material-blue/views/account/linkedAccounts.inc:18
@@ -2775,7 +2803,7 @@ msgid "Editar Cuenta"
msgstr "Edit Account"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:389
+#: ../../../modules/web/Controllers/AccountController.php:388
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:334
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:335
#: ../../../modules/web/Controllers/Helpers/Grid/AccountGrid.php:176
@@ -2787,26 +2815,26 @@ msgstr "Edit Account"
msgid "Eliminar Cuenta"
msgstr "Remove Account"
-#: ../../../modules/web/Controllers/AccountController.php:432
+#: ../../../modules/web/Controllers/AccountController.php:431
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:155
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:156
msgid "Modificar Clave de Cuenta"
msgstr "Edit Account Password"
-#: ../../../modules/web/Controllers/AccountController.php:649
-#: ../../../modules/web/Controllers/AccountController.php:683
+#: ../../../modules/web/Controllers/AccountController.php:648
+#: ../../../modules/web/Controllers/AccountController.php:682
msgid "Clave copiada"
msgstr "Password copied"
-#: ../../../modules/web/Controllers/AccountController.php:843
-#: ../../../modules/web/Controllers/AccountController.php:854
+#: ../../../modules/web/Controllers/AccountController.php:842
+#: ../../../modules/web/Controllers/AccountController.php:853
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:145
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:150
msgid "Cuenta restaurada"
msgstr "Account restored"
-#: ../../../modules/web/Controllers/AccountController.php:879
-#: ../../../modules/web/Controllers/AccountController.php:882
+#: ../../../modules/web/Controllers/AccountController.php:878
+#: ../../../modules/web/Controllers/AccountController.php:881
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:99
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:102
#: ../../../modules/web/Controllers/AccountManagerController.php:131
@@ -2814,16 +2842,16 @@ msgstr "Account restored"
msgid "Cuentas eliminadas"
msgstr "Accounts removed"
-#: ../../../modules/web/Controllers/AccountController.php:919
+#: ../../../modules/web/Controllers/AccountController.php:918
#: ../../../modules/web/Forms/NotificationForm.php:100
msgid "Es necesaria una descripción"
msgstr "A description is needed"
-#: ../../../modules/web/Controllers/AccountController.php:927
+#: ../../../modules/web/Controllers/AccountController.php:926
msgid "Solicitante"
msgstr "Requester"
-#: ../../../modules/web/Controllers/AccountController.php:930
+#: ../../../modules/web/Controllers/AccountController.php:929
#: ../../../modules/web/Controllers/Helpers/Grid/CategoryGrid.php:106
#: ../../../modules/web/Controllers/Helpers/Grid/ClientGrid.php:105
#: ../../../modules/web/Controllers/Helpers/Grid/EventlogGrid.php:105
@@ -2837,7 +2865,7 @@ msgstr "Requester"
msgid "Descripción"
msgstr "Description"
-#: ../../../modules/web/Controllers/AccountController.php:943
+#: ../../../modules/web/Controllers/AccountController.php:942
msgid "Solicitud realizada"
msgstr "Request done"
@@ -3066,7 +3094,7 @@ msgid "Ey, esto es una DEMO!!"
msgstr "Ey, this is a DEMO!!"
#: ../../../modules/web/Controllers/ConfigBackupController.php:86
-#: ../../../modules/web/Controllers/UserPassResetController.php:173
+#: ../../../modules/web/Controllers/UserPassResetController.php:176
#: ../../../modules/web/Forms/AccountForm.php:135
#: ../../../modules/web/Forms/UserForm.php:161
msgid "Las claves no coinciden"
@@ -3951,15 +3979,11 @@ msgid "Eliminar Notificación"
msgstr "Delete Notification"
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:89
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:334
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:336
#: ../../../modules/web/themes/material-blue/views/plugin/index.inc:1
msgid "Plugins"
msgstr "Plugins"
-#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:101
-msgid "Plugin"
-msgstr "Plugin"
-
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:118
msgid "No disponible"
msgstr "Unavailable"
@@ -3973,7 +3997,7 @@ msgstr "Search for Plugin"
#. (itstool) path: action/text
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:149
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:150
-#: ../../../modules/web/Controllers/PluginController.php:120
+#: ../../../modules/web/Controllers/PluginController.php:125
#: ../../../config/actions.xml:541
msgid "Ver Plugin"
msgstr "View Plugin"
@@ -4224,13 +4248,13 @@ msgstr "Edit Profile"
msgid "Eliminar Perfil"
msgstr "Delete Profile"
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:265
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:267
#: ../../../modules/web/themes/material-blue/inc/Icons.php:58
msgid "Buscar"
msgstr "Search"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:348
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:350
#: ../../../modules/web/themes/material-blue/inc/Icons.php:61
#: ../../../modules/web/themes/material-blue/views/config/ldap.inc:21
#: ../../../modules/web/themes/material-blue/views/itemshow/user_profile.inc:22
@@ -4282,15 +4306,15 @@ msgstr "Value created"
msgid "Valor actualizado"
msgstr "Value updated"
-#: ../../../modules/web/Controllers/LoginController.php:101
+#: ../../../modules/web/Controllers/LoginController.php:119
msgid "Finalizar sesión"
msgstr "Logout session"
-#: ../../../modules/web/Controllers/LoginController.php:103
+#: ../../../modules/web/Controllers/LoginController.php:121
msgid "Tiempo inactivo"
msgstr "Inactive time"
-#: ../../../modules/web/Controllers/LoginController.php:104
+#: ../../../modules/web/Controllers/LoginController.php:122
msgid "Tiempo total"
msgstr "Total time"
@@ -4319,18 +4343,13 @@ msgstr "Notification created"
msgid "Notificación actualizada"
msgstr "Notification updated"
-#: ../../../modules/web/Controllers/PluginController.php:181
-#: ../../../modules/web/Controllers/PluginController.php:184
+#: ../../../modules/web/Controllers/PluginController.php:188
+#: ../../../modules/web/Controllers/PluginController.php:191
msgid "Plugin habilitado"
msgstr "Plugin enabled"
-#: ../../../modules/web/Controllers/PluginController.php:206
-#: ../../../modules/web/Controllers/PluginController.php:209
-msgid "Plugin deshabilitado"
-msgstr "Plugin disabled"
-
-#: ../../../modules/web/Controllers/PluginController.php:231
-#: ../../../modules/web/Controllers/PluginController.php:234
+#: ../../../modules/web/Controllers/PluginController.php:238
+#: ../../../modules/web/Controllers/PluginController.php:241
msgid "Plugin restablecido"
msgstr "Plugin reset"
@@ -4357,11 +4376,11 @@ msgstr "Link deleted"
msgid "Enlace creado"
msgstr "Link created"
-#: ../../../modules/web/Controllers/StatusController.php:94
+#: ../../../modules/web/Controllers/StatusController.php:93
msgid "Versión no disponible"
msgstr "Version unavailable"
-#: ../../../modules/web/Controllers/StatusController.php:142
+#: ../../../modules/web/Controllers/StatusController.php:140
msgid "Notificaciones no disponibles"
msgstr "Notifications not available"
@@ -4467,7 +4486,7 @@ msgstr "Request sent"
msgid "En breve recibirá un correo para completar la solicitud."
msgstr "You will receive an email to complete the request shortly."
-#: ../../../modules/web/Controllers/UserPassResetController.php:169
+#: ../../../modules/web/Controllers/UserPassResetController.php:172
#: ../../../modules/web/Forms/AuthTokenForm.php:101
#: ../../../modules/web/Forms/UserForm.php:157
msgid "La clave no puede estar en blanco"
@@ -4501,7 +4520,7 @@ msgstr "View Profile"
msgid "Preferencias actualizadas"
msgstr "Preferences updated"
-#: ../../../modules/web/Controllers/UserSettingsManagerController.php:89
+#: ../../../modules/web/Controllers/UserSettingsManagerController.php:92
msgid "Preferencias"
msgstr "Preferences"
diff --git a/app/locales/en_US/LC_MESSAGES/messages.mo b/app/locales/en_US/LC_MESSAGES/messages.mo
index eb83bf9e..9b1e1e80 100644
Binary files a/app/locales/en_US/LC_MESSAGES/messages.mo and b/app/locales/en_US/LC_MESSAGES/messages.mo differ
diff --git a/app/locales/en_US/LC_MESSAGES/messages.po b/app/locales/en_US/LC_MESSAGES/messages.po
index 0696425f..7006c1dc 100644
--- a/app/locales/en_US/LC_MESSAGES/messages.po
+++ b/app/locales/en_US/LC_MESSAGES/messages.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: sysPass\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-10-12 00:42+0200\n"
-"PO-Revision-Date: 2018-10-12 00:43+0200\n"
+"POT-Creation-Date: 2018-10-15 02:52+0200\n"
+"PO-Revision-Date: 2018-10-15 02:53+0200\n"
"Last-Translator: nuxsmin \n"
"Language-Team: nuxsmin@syspass.org\n"
"Language: en_US\n"
@@ -25,12 +25,12 @@ msgstr ""
"X-Poedit-SearchPath-1: ../../../../lib\n"
"X-Poedit-SearchPath-2: ../../../config\n"
-#: ../../../../lib/SP/Bootstrap.php:267
+#: ../../../../lib/SP/Bootstrap.php:278
#, php-format
msgid "Versión de PHP requerida >= %s <= %s"
msgstr "Required PHP version >= %s <= %s"
-#: ../../../../lib/SP/Bootstrap.php:269
+#: ../../../../lib/SP/Bootstrap.php:280
msgid ""
"Actualice la versión de PHP para que la aplicación funcione correctamente"
msgstr "Please update the PHP version to run sysPass"
@@ -53,7 +53,7 @@ msgid "Actual: %s - Necesario: 750"
msgstr "Current: %s - Needed: 750"
#: ../../../../lib/SP/Core/Acl/AccountPermissionException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:132
+#: ../../../../lib/SP/Util/ErrorUtil.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:96
msgid "No tiene permisos para acceder a esta cuenta"
msgstr "You don't have permission to access to this account"
@@ -61,12 +61,12 @@ msgstr "You don't have permission to access to this account"
#: ../../../../lib/SP/Core/Acl/AccountPermissionException.php:45
#: ../../../../lib/SP/Core/Acl/UnauthorizedActionException.php:46
#: ../../../../lib/SP/Core/Acl/UnauthorizedPageException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:129
-#: ../../../../lib/SP/Util/ErrorUtil.php:133
-#: ../../../../lib/SP/Util/ErrorUtil.php:137
-#: ../../../../lib/SP/Util/ErrorUtil.php:141
-#: ../../../../lib/SP/Util/ErrorUtil.php:149
-#: ../../../../lib/SP/Util/ErrorUtil.php:156
+#: ../../../../lib/SP/Util/ErrorUtil.php:139
+#: ../../../../lib/SP/Util/ErrorUtil.php:143
+#: ../../../../lib/SP/Util/ErrorUtil.php:147
+#: ../../../../lib/SP/Util/ErrorUtil.php:151
+#: ../../../../lib/SP/Util/ErrorUtil.php:159
+#: ../../../../lib/SP/Util/ErrorUtil.php:166
#: ../../../modules/web/Controllers/ErrorController.php:124
#: ../../../modules/web/Controllers/UserPassResetController.php:94
#: ../../../modules/web/themes/material-blue/views/upgrade/index.inc:13
@@ -75,7 +75,7 @@ msgstr "Please contact to the administrator"
# Not available
#: ../../../../lib/SP/Core/Acl/Acl.php:294
-#: ../../../../lib/SP/Services/Auth/LoginService.php:600
+#: ../../../../lib/SP/Services/Auth/LoginService.php:604
msgid "N/D"
msgstr "N/A"
@@ -96,24 +96,24 @@ msgstr "Action"
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapMsAds.php:155
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapStd.php:110
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapStd.php:142
-#: ../../../../lib/SP/Services/Auth/LoginService.php:217
-#: ../../../../lib/SP/Services/Auth/LoginService.php:235
-#: ../../../../lib/SP/Services/Auth/LoginService.php:386
-#: ../../../../lib/SP/Services/Auth/LoginService.php:453
-#: ../../../../lib/SP/Services/Auth/LoginService.php:561
-#: ../../../../lib/SP/Services/Auth/LoginService.php:604
+#: ../../../../lib/SP/Services/Auth/LoginService.php:220
+#: ../../../../lib/SP/Services/Auth/LoginService.php:238
+#: ../../../../lib/SP/Services/Auth/LoginService.php:390
+#: ../../../../lib/SP/Services/Auth/LoginService.php:457
+#: ../../../../lib/SP/Services/Auth/LoginService.php:565
+#: ../../../../lib/SP/Services/Auth/LoginService.php:608
#: ../../../../lib/SP/Services/Ldap/LdapImportService.php:238
#: ../../../modules/web/Controllers/Helpers/Account/AccountSearchHelper.php:253
#: ../../../modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php:106
#: ../../../modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php:107
#: ../../../modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php:111
#: ../../../modules/web/Controllers/Helpers/Grid/TrackGrid.php:105
-#: ../../../modules/web/Controllers/LoginController.php:102
+#: ../../../modules/web/Controllers/LoginController.php:120
#: ../../../modules/web/Controllers/UserController.php:278
#: ../../../modules/web/Controllers/UserController.php:312
#: ../../../modules/web/Controllers/UserController.php:373
#: ../../../modules/web/Controllers/UserController.php:412
-#: ../../../modules/web/Controllers/UserPassResetController.php:187
+#: ../../../modules/web/Controllers/UserPassResetController.php:190
#: ../../../modules/web/themes/material-blue/views/account/account-editpass.inc:55
#: ../../../modules/web/themes/material-blue/views/account/account-editpass.inc:61
#: ../../../modules/web/themes/material-blue/views/account/account-history.inc:91
@@ -151,7 +151,7 @@ msgid "Acción no encontrada"
msgstr "Action not found"
#: ../../../../lib/SP/Core/Acl/UnauthorizedActionException.php:46
-#: ../../../../lib/SP/Util/ErrorUtil.php:140
+#: ../../../../lib/SP/Util/ErrorUtil.php:150
#: ../../../modules/web/Controllers/AccountFileController.php:261
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:59
#: ../../../modules/web/Controllers/AccountManagerController.php:77
@@ -200,8 +200,8 @@ msgstr "Action not found"
#: ../../../modules/web/Controllers/NotificationController.php:288
#: ../../../modules/web/Controllers/NotificationController.php:315
#: ../../../modules/web/Controllers/NotificationController.php:348
-#: ../../../modules/web/Controllers/PluginController.php:98
-#: ../../../modules/web/Controllers/PluginController.php:117
+#: ../../../modules/web/Controllers/PluginController.php:103
+#: ../../../modules/web/Controllers/PluginController.php:122
#: ../../../modules/web/Controllers/PublicLinkController.php:71
#: ../../../modules/web/Controllers/PublicLinkController.php:105
#: ../../../modules/web/Controllers/PublicLinkController.php:167
@@ -244,7 +244,7 @@ msgid "No tiene permisos para realizar esta operación"
msgstr "You don't have permission to do this operation"
#: ../../../../lib/SP/Core/Acl/UnauthorizedPageException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:136
+#: ../../../../lib/SP/Util/ErrorUtil.php:146
msgid "No tiene permisos para acceder a esta página"
msgstr "You don't have permission to access this page"
@@ -280,14 +280,14 @@ msgstr "Session cannot be initialized"
#: ../../../../lib/SP/Services/Account/AccountService.php:227
#: ../../../../lib/SP/Services/Account/AccountService.php:232
#: ../../../../lib/SP/Services/Api/ApiService.php:129
-#: ../../../../lib/SP/Services/Api/ApiService.php:227
-#: ../../../../lib/SP/Services/Api/ApiService.php:235
-#: ../../../../lib/SP/Services/Auth/LoginService.php:187
-#: ../../../../lib/SP/Services/Auth/LoginService.php:351
-#: ../../../../lib/SP/Services/Auth/LoginService.php:500
-#: ../../../../lib/SP/Services/Auth/LoginService.php:505
-#: ../../../../lib/SP/Services/Auth/LoginService.php:537
-#: ../../../../lib/SP/Services/Auth/LoginService.php:644
+#: ../../../../lib/SP/Services/Api/ApiService.php:229
+#: ../../../../lib/SP/Services/Api/ApiService.php:237
+#: ../../../../lib/SP/Services/Auth/LoginService.php:190
+#: ../../../../lib/SP/Services/Auth/LoginService.php:354
+#: ../../../../lib/SP/Services/Auth/LoginService.php:504
+#: ../../../../lib/SP/Services/Auth/LoginService.php:509
+#: ../../../../lib/SP/Services/Auth/LoginService.php:541
+#: ../../../../lib/SP/Services/Auth/LoginService.php:648
#: ../../../../lib/SP/Services/AuthToken/AuthTokenService.php:311
#: ../../../../lib/SP/Services/CustomField/CustomFieldService.php:203
#: ../../../../lib/SP/Services/Export/XmlVerifyService.php:108
@@ -306,7 +306,7 @@ msgstr "Crypto module cannot be loaded"
msgid "Error al generar datos cifrados"
msgstr "Error while creating the encrypted data"
-#: ../../../../lib/SP/Core/Events/Event.php:56
+#: ../../../../lib/SP/Core/Events/Event.php:57
msgid "Es necesario un objeto"
msgstr "An object is needed"
@@ -320,17 +320,17 @@ msgstr "Invalid icons class"
#: ../../../../lib/SP/DataModel/PublicLinkListData.php:88
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapConnection.php:190
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "ON"
msgstr "ON"
#: ../../../../lib/SP/DataModel/PublicLinkListData.php:88
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "OFF"
msgstr "OFF"
#: ../../../../lib/SP/Html/DataGrid/DataGridBase.php:303
-#: ../../../../lib/SP/Mvc/View/Template.php:122
+#: ../../../../lib/SP/Mvc/View/Template.php:126
#, php-format
msgid "No es posible obtener la plantilla \"%s\" : %s"
msgstr "Unable to retrieve the \"%s\" template: %s"
@@ -352,11 +352,11 @@ msgstr "Encoding error"
msgid "Respuesta XML-RPC inválida"
msgstr "Invalid XML-RPC response"
-#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:64
+#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:71
msgid "La sesión no se ha iniciado o ha caducado"
msgstr "Session not started or timed out"
-#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:114
+#: ../../../../lib/SP/Mvc/Controller/ControllerTrait.php:124
msgid "Acción Inválida"
msgstr "Invalid Action"
@@ -398,41 +398,69 @@ msgstr "Invalid filter type"
msgid "Tipo de objeto incorrecto"
msgstr "Wrong object type"
-#: ../../../../lib/SP/Mvc/View/Template.php:274
-#: ../../../../lib/SP/Mvc/View/Template.php:276
+#: ../../../../lib/SP/Mvc/View/Template.php:278
+#: ../../../../lib/SP/Mvc/View/Template.php:280
#, php-format
msgid "No es posible obtener la variable \"%s\""
msgstr "Unable to retrieve the \"%s\" variable"
-#: ../../../../lib/SP/Mvc/View/Template.php:322
-#: ../../../../lib/SP/Mvc/View/Template.php:324
+#: ../../../../lib/SP/Mvc/View/Template.php:326
+#: ../../../../lib/SP/Mvc/View/Template.php:328
#, php-format
msgid "No es posible destruir la variable \"%s\""
msgstr "Unable to unset the \"%s\" variable"
-#: ../../../../lib/SP/Mvc/View/Template.php:341
+#: ../../../../lib/SP/Mvc/View/Template.php:345
msgid "La plantilla no contiene archivos"
msgstr "Template does not contain files"
-#: ../../../../lib/SP/Plugin/PluginManager.php:113
-#: ../../../../lib/SP/Plugin/PluginManager.php:256
+#: ../../../../lib/SP/Plugin/PluginManager.php:170
+#, php-format
+msgid "Versión de plugin no compatible (%s)"
+msgstr "Plugin version not compatible (%s)"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:192
#, php-format
msgid "No es posible cargar el plugin \"%s\""
msgstr "Unable to load the \"%s\" plugin"
+#: ../../../../lib/SP/Plugin/PluginManager.php:194
+#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:101
+msgid "Plugin"
+msgstr "Plugin"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:219
+#: ../../../../lib/SP/Plugin/PluginManager.php:339
+#: ../../../modules/web/Controllers/PluginController.php:213
+#: ../../../modules/web/Controllers/PluginController.php:216
+msgid "Plugin deshabilitado"
+msgstr "Plugin disabled"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:254
+msgid "Plugin disponible"
+msgstr "Plugin available"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:264
+msgid "Plugin no disponible"
+msgstr "Plugin unavailable"
+
+#: ../../../../lib/SP/Plugin/PluginManager.php:294
+msgid "Plugin cargado"
+msgstr "Plugin loaded"
+
#. (itstool) path: action/text
-#: ../../../../lib/SP/Plugin/PluginManager.php:245
+#: ../../../../lib/SP/Plugin/PluginManager.php:319
#: ../../../config/actions.xml:535
msgid "Nuevo Plugin"
msgstr "New Plugin"
-#: ../../../../lib/SP/Plugin/PluginManager.php:246
+#: ../../../../lib/SP/Plugin/PluginManager.php:320
#: ../../../modules/api/Controllers/AccountController.php:71
#: ../../../modules/api/Controllers/AccountController.php:103
#: ../../../modules/api/Controllers/AccountController.php:139
-#: ../../../modules/api/Controllers/AccountController.php:185
-#: ../../../modules/api/Controllers/AccountController.php:235
-#: ../../../modules/api/Controllers/AccountController.php:310
+#: ../../../modules/api/Controllers/AccountController.php:189
+#: ../../../modules/api/Controllers/AccountController.php:240
+#: ../../../modules/api/Controllers/AccountController.php:315
#: ../../../modules/api/Controllers/CategoryController.php:63
#: ../../../modules/api/Controllers/CategoryController.php:92
#: ../../../modules/api/Controllers/CategoryController.php:122
@@ -490,7 +518,7 @@ msgid "Método ya inicializado"
msgstr "Method already initialized"
#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:119
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:125
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:126
msgid "Error al buscar RDN de grupo"
msgstr "Error while searching the group RDN"
@@ -518,13 +546,13 @@ msgstr "Error while searching the group RDN"
msgid "Grupo"
msgstr "Group"
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:200
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:204
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:205
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:210
msgid "Error al localizar el usuario en LDAP"
msgstr "Error while searching the user on LDAP"
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:249
-#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:254
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:259
+#: ../../../../lib/SP/Providers/Auth/Ldap/LdapActions.php:265
msgid "Error al buscar objetos en DN base"
msgstr "Error while searching objects in base DN"
@@ -594,7 +622,7 @@ msgid "No es posible inicializar"
msgstr "Unable to initialize"
#: ../../../../lib/SP/Providers/Notification/NotificationHandler.php:124
-#: ../../../modules/web/Controllers/AccountController.php:926
+#: ../../../modules/web/Controllers/AccountController.php:925
msgid "Solicitud"
msgstr "Request"
@@ -1121,7 +1149,7 @@ msgstr "The account doesn't exist"
#: ../../../../lib/SP/Services/Api/ApiRequest.php:79
#: ../../../../lib/SP/Services/Api/ApiRequest.php:113
-#: ../../../../lib/SP/Services/Api/ApiService.php:229
+#: ../../../../lib/SP/Services/Api/ApiService.php:231
msgid "Datos inválidos"
msgstr "Invalid data"
@@ -1130,7 +1158,7 @@ msgid "Fomato incorrecto"
msgstr "Invalid format"
#: ../../../../lib/SP/Services/Api/ApiService.php:96
-#: ../../../../lib/SP/Services/Auth/LoginService.php:137
+#: ../../../../lib/SP/Services/Auth/LoginService.php:138
#: ../../../../lib/SP/Services/UserPassRecover/UserPassRecoverService.php:103
#: ../../../modules/web/Controllers/UserPassResetController.php:124
msgid "Intentos excedidos"
@@ -1145,54 +1173,54 @@ msgstr "Wrong parameters"
msgid "Acceso no permitido"
msgstr "Unauthorized access"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:157
-#: ../../../../lib/SP/Services/Auth/LoginService.php:456
-#: ../../../../lib/SP/Services/Auth/LoginService.php:463
-#: ../../../../lib/SP/Services/Auth/LoginService.php:571
-#: ../../../../lib/SP/Services/Auth/LoginService.php:576
-#: ../../../../lib/SP/Services/Auth/LoginService.php:615
-#: ../../../../lib/SP/Services/Auth/LoginService.php:620
+#: ../../../../lib/SP/Services/Auth/LoginService.php:160
+#: ../../../../lib/SP/Services/Auth/LoginService.php:460
+#: ../../../../lib/SP/Services/Auth/LoginService.php:467
+#: ../../../../lib/SP/Services/Auth/LoginService.php:575
+#: ../../../../lib/SP/Services/Auth/LoginService.php:580
+#: ../../../../lib/SP/Services/Auth/LoginService.php:619
+#: ../../../../lib/SP/Services/Auth/LoginService.php:624
msgid "Login incorrecto"
msgstr "Wrong login"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:216
-#: ../../../../lib/SP/Services/Auth/LoginService.php:223
+#: ../../../../lib/SP/Services/Auth/LoginService.php:219
+#: ../../../../lib/SP/Services/Auth/LoginService.php:226
msgid "Usuario deshabilitado"
msgstr "User disabled"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:270
+#: ../../../../lib/SP/Services/Auth/LoginService.php:273
msgid "Usando clave temporal"
msgstr "Using temporary password"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:282
-#: ../../../../lib/SP/Services/Auth/LoginService.php:288
-#: ../../../../lib/SP/Services/Auth/LoginService.php:306
-#: ../../../../lib/SP/Services/Auth/LoginService.php:312
+#: ../../../../lib/SP/Services/Auth/LoginService.php:285
+#: ../../../../lib/SP/Services/Auth/LoginService.php:291
+#: ../../../../lib/SP/Services/Auth/LoginService.php:309
+#: ../../../../lib/SP/Services/Auth/LoginService.php:315
msgid "Clave maestra incorrecta"
msgstr "Wrong master password"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:297
-#: ../../../../lib/SP/Services/Auth/LoginService.php:321
+#: ../../../../lib/SP/Services/Auth/LoginService.php:300
+#: ../../../../lib/SP/Services/Auth/LoginService.php:324
#: ../../../../lib/SP/Services/User/UpdatedMasterPassException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:144
+#: ../../../../lib/SP/Util/ErrorUtil.php:154
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:68
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:116
msgid "Clave maestra actualizada"
msgstr "Master password updated"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:327
+#: ../../../../lib/SP/Services/Auth/LoginService.php:330
msgid "Es necesaria su clave anterior"
msgstr "Your previous password is needed"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:339
+#: ../../../../lib/SP/Services/Auth/LoginService.php:342
msgid "La clave maestra no ha sido guardada o es incorrecta"
msgstr "The Master Password either is not saved or is wrong"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:451
-#: ../../../../lib/SP/Services/Auth/LoginService.php:514
-#: ../../../../lib/SP/Services/Auth/LoginService.php:560
-#: ../../../../lib/SP/Services/Auth/LoginService.php:603
+#: ../../../../lib/SP/Services/Auth/LoginService.php:455
+#: ../../../../lib/SP/Services/Auth/LoginService.php:518
+#: ../../../../lib/SP/Services/Auth/LoginService.php:564
+#: ../../../../lib/SP/Services/Auth/LoginService.php:607
#: ../../../modules/web/Controllers/AccountFileController.php:235
#: ../../../modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php:108
#: ../../../modules/web/Controllers/Helpers/Grid/FileGrid.php:108
@@ -1207,22 +1235,22 @@ msgstr "The Master Password either is not saved or is wrong"
msgid "Tipo"
msgstr "Type"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:452
-#: ../../../../lib/SP/Services/Auth/LoginService.php:515
+#: ../../../../lib/SP/Services/Auth/LoginService.php:456
+#: ../../../../lib/SP/Services/Auth/LoginService.php:519
msgid "Servidor LDAP"
msgstr "LDAP Server"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:471
-#: ../../../../lib/SP/Services/Auth/LoginService.php:476
+#: ../../../../lib/SP/Services/Auth/LoginService.php:475
+#: ../../../../lib/SP/Services/Auth/LoginService.php:480
msgid "Cuenta expirada"
msgstr "Account expired"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:484
-#: ../../../../lib/SP/Services/Auth/LoginService.php:489
+#: ../../../../lib/SP/Services/Auth/LoginService.php:488
+#: ../../../../lib/SP/Services/Auth/LoginService.php:493
msgid "El usuario no tiene grupos asociados"
msgstr "The user has no associated groups"
-#: ../../../../lib/SP/Services/Auth/LoginService.php:605
+#: ../../../../lib/SP/Services/Auth/LoginService.php:609
#: ../../../modules/web/themes/material-blue/views/config/general-auth.inc:10
msgid "Autentificación"
msgstr "Authentication"
@@ -1503,16 +1531,16 @@ msgstr "Account imported"
#: ../../../modules/api/Controllers/AccountController.php:72
#: ../../../modules/api/Controllers/AccountController.php:104
#: ../../../modules/api/Controllers/AccountController.php:140
-#: ../../../modules/api/Controllers/AccountController.php:186
-#: ../../../modules/api/Controllers/AccountController.php:236
-#: ../../../modules/api/Controllers/AccountController.php:311
-#: ../../../modules/web/Controllers/AccountController.php:225
-#: ../../../modules/web/Controllers/AccountController.php:720
-#: ../../../modules/web/Controllers/AccountController.php:765
-#: ../../../modules/web/Controllers/AccountController.php:806
-#: ../../../modules/web/Controllers/AccountController.php:845
-#: ../../../modules/web/Controllers/AccountController.php:895
-#: ../../../modules/web/Controllers/AccountController.php:929
+#: ../../../modules/api/Controllers/AccountController.php:190
+#: ../../../modules/api/Controllers/AccountController.php:241
+#: ../../../modules/api/Controllers/AccountController.php:316
+#: ../../../modules/web/Controllers/AccountController.php:224
+#: ../../../modules/web/Controllers/AccountController.php:719
+#: ../../../modules/web/Controllers/AccountController.php:764
+#: ../../../modules/web/Controllers/AccountController.php:805
+#: ../../../modules/web/Controllers/AccountController.php:844
+#: ../../../modules/web/Controllers/AccountController.php:894
+#: ../../../modules/web/Controllers/AccountController.php:928
#: ../../../modules/web/Controllers/AccountFileController.php:234
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:112
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:147
@@ -2119,7 +2147,7 @@ msgid "Enlace"
msgstr "Link"
#: ../../../../lib/SP/Services/User/UpdatedMasterPassException.php:45
-#: ../../../../lib/SP/Util/ErrorUtil.php:145
+#: ../../../../lib/SP/Util/ErrorUtil.php:155
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:68
#: ../../../modules/web/Controllers/ConfigEncryptionController.php:142
#: ../../../modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php:116
@@ -2286,12 +2314,12 @@ msgstr "Socket not initialized"
msgid "Error al enviar datos"
msgstr "Error while sending the data"
-#: ../../../../lib/SP/Util/ErrorUtil.php:128
+#: ../../../../lib/SP/Util/ErrorUtil.php:138
msgid "Opción no disponible"
msgstr "Option unavailable"
-#: ../../../../lib/SP/Util/ErrorUtil.php:148
-#: ../../../../lib/SP/Util/ErrorUtil.php:155
+#: ../../../../lib/SP/Util/ErrorUtil.php:158
+#: ../../../../lib/SP/Util/ErrorUtil.php:165
msgid "Se ha producido una excepción"
msgstr "An exception occured"
@@ -2304,40 +2332,40 @@ msgid "Cuenta visualizada"
msgstr "Account displayed"
#: ../../../modules/api/Controllers/AccountController.php:102
-#: ../../../modules/web/Controllers/AccountController.php:554
-#: ../../../modules/web/Controllers/AccountController.php:610
+#: ../../../modules/web/Controllers/AccountController.php:553
+#: ../../../modules/web/Controllers/AccountController.php:609
msgid "Clave visualizada"
msgstr "Password viewed"
#: ../../../modules/api/Controllers/AccountController.php:138
#: ../../../modules/api/Controllers/AccountController.php:144
-#: ../../../modules/web/Controllers/AccountController.php:804
-#: ../../../modules/web/Controllers/AccountController.php:815
+#: ../../../modules/web/Controllers/AccountController.php:803
+#: ../../../modules/web/Controllers/AccountController.php:814
#: ../../../modules/web/Controllers/UserController.php:411
#: ../../../modules/web/Controllers/UserController.php:415
-#: ../../../modules/web/Controllers/UserPassResetController.php:186
-#: ../../../modules/web/Controllers/UserPassResetController.php:190
+#: ../../../modules/web/Controllers/UserPassResetController.php:189
+#: ../../../modules/web/Controllers/UserPassResetController.php:193
msgid "Clave actualizada"
msgstr "Password updated"
-#: ../../../modules/api/Controllers/AccountController.php:184
-#: ../../../modules/api/Controllers/AccountController.php:190
-#: ../../../modules/web/Controllers/AccountController.php:718
-#: ../../../modules/web/Controllers/AccountController.php:729
+#: ../../../modules/api/Controllers/AccountController.php:188
+#: ../../../modules/api/Controllers/AccountController.php:194
+#: ../../../modules/web/Controllers/AccountController.php:717
+#: ../../../modules/web/Controllers/AccountController.php:728
msgid "Cuenta creada"
msgstr "Account added"
-#: ../../../modules/api/Controllers/AccountController.php:234
-#: ../../../modules/api/Controllers/AccountController.php:240
-#: ../../../modules/web/Controllers/AccountController.php:763
-#: ../../../modules/web/Controllers/AccountController.php:774
+#: ../../../modules/api/Controllers/AccountController.php:239
+#: ../../../modules/api/Controllers/AccountController.php:245
+#: ../../../modules/web/Controllers/AccountController.php:762
+#: ../../../modules/web/Controllers/AccountController.php:773
msgid "Cuenta actualizada"
msgstr "Account updated"
-#: ../../../modules/api/Controllers/AccountController.php:309
-#: ../../../modules/api/Controllers/AccountController.php:315
-#: ../../../modules/web/Controllers/AccountController.php:893
-#: ../../../modules/web/Controllers/AccountController.php:898
+#: ../../../modules/api/Controllers/AccountController.php:314
+#: ../../../modules/api/Controllers/AccountController.php:320
+#: ../../../modules/web/Controllers/AccountController.php:892
+#: ../../../modules/web/Controllers/AccountController.php:897
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:110
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:115
#: ../../../modules/web/Controllers/AccountManagerController.php:145
@@ -2709,9 +2737,9 @@ msgstr "Group deleted"
msgid "Es necesario actualizar"
msgstr "Updating needed"
-#: ../../../modules/web/Controllers/AccountController.php:149
-#: ../../../modules/web/Controllers/AccountController.php:204
-#: ../../../modules/web/Controllers/AccountController.php:474
+#: ../../../modules/web/Controllers/AccountController.php:148
+#: ../../../modules/web/Controllers/AccountController.php:203
+#: ../../../modules/web/Controllers/AccountController.php:473
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:60
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:61
#: ../../../modules/web/Controllers/Helpers/Grid/AccountGrid.php:159
@@ -2721,21 +2749,21 @@ msgstr "Updating needed"
msgid "Detalles de Cuenta"
msgstr "Account Details"
-#: ../../../modules/web/Controllers/AccountController.php:223
+#: ../../../modules/web/Controllers/AccountController.php:222
msgid "Enlace visualizado"
msgstr "Link viewed"
-#: ../../../modules/web/Controllers/AccountController.php:224
-#: ../../../modules/web/Controllers/AccountController.php:555
-#: ../../../modules/web/Controllers/AccountController.php:611
-#: ../../../modules/web/Controllers/AccountController.php:650
-#: ../../../modules/web/Controllers/AccountController.php:684
-#: ../../../modules/web/Controllers/AccountController.php:719
-#: ../../../modules/web/Controllers/AccountController.php:764
-#: ../../../modules/web/Controllers/AccountController.php:805
-#: ../../../modules/web/Controllers/AccountController.php:844
-#: ../../../modules/web/Controllers/AccountController.php:894
-#: ../../../modules/web/Controllers/AccountController.php:928
+#: ../../../modules/web/Controllers/AccountController.php:223
+#: ../../../modules/web/Controllers/AccountController.php:554
+#: ../../../modules/web/Controllers/AccountController.php:610
+#: ../../../modules/web/Controllers/AccountController.php:649
+#: ../../../modules/web/Controllers/AccountController.php:683
+#: ../../../modules/web/Controllers/AccountController.php:718
+#: ../../../modules/web/Controllers/AccountController.php:763
+#: ../../../modules/web/Controllers/AccountController.php:804
+#: ../../../modules/web/Controllers/AccountController.php:843
+#: ../../../modules/web/Controllers/AccountController.php:893
+#: ../../../modules/web/Controllers/AccountController.php:927
#: ../../../modules/web/Controllers/AccountFileController.php:233
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:111
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:146
@@ -2749,24 +2777,24 @@ msgstr "Link viewed"
msgid "Cuenta"
msgstr "Account"
-#: ../../../modules/web/Controllers/AccountController.php:226
+#: ../../../modules/web/Controllers/AccountController.php:225
msgid "Agente"
msgstr "Agent"
-#: ../../../modules/web/Controllers/AccountController.php:227
+#: ../../../modules/web/Controllers/AccountController.php:226
msgid "HTTPS"
msgstr "HTTPS"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:256
-#: ../../../modules/web/Controllers/AccountController.php:300
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:278
+#: ../../../modules/web/Controllers/AccountController.php:255
+#: ../../../modules/web/Controllers/AccountController.php:299
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:280
#: ../../../config/actions.xml:157
msgid "Nueva Cuenta"
msgstr "New Account"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:344
+#: ../../../modules/web/Controllers/AccountController.php:343
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:176
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:177
#: ../../../modules/web/themes/material-blue/views/account/linkedAccounts.inc:18
@@ -2775,7 +2803,7 @@ msgid "Editar Cuenta"
msgstr "Edit Account"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/AccountController.php:389
+#: ../../../modules/web/Controllers/AccountController.php:388
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:334
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:335
#: ../../../modules/web/Controllers/Helpers/Grid/AccountGrid.php:176
@@ -2787,26 +2815,26 @@ msgstr "Edit Account"
msgid "Eliminar Cuenta"
msgstr "Remove Account"
-#: ../../../modules/web/Controllers/AccountController.php:432
+#: ../../../modules/web/Controllers/AccountController.php:431
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:155
#: ../../../modules/web/Controllers/Helpers/Account/AccountActionsHelper.php:156
msgid "Modificar Clave de Cuenta"
msgstr "Edit Account Password"
-#: ../../../modules/web/Controllers/AccountController.php:649
-#: ../../../modules/web/Controllers/AccountController.php:683
+#: ../../../modules/web/Controllers/AccountController.php:648
+#: ../../../modules/web/Controllers/AccountController.php:682
msgid "Clave copiada"
msgstr "Password copied"
-#: ../../../modules/web/Controllers/AccountController.php:843
-#: ../../../modules/web/Controllers/AccountController.php:854
+#: ../../../modules/web/Controllers/AccountController.php:842
+#: ../../../modules/web/Controllers/AccountController.php:853
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:145
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:150
msgid "Cuenta restaurada"
msgstr "Account restored"
-#: ../../../modules/web/Controllers/AccountController.php:879
-#: ../../../modules/web/Controllers/AccountController.php:882
+#: ../../../modules/web/Controllers/AccountController.php:878
+#: ../../../modules/web/Controllers/AccountController.php:881
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:99
#: ../../../modules/web/Controllers/AccountHistoryManagerController.php:102
#: ../../../modules/web/Controllers/AccountManagerController.php:131
@@ -2814,16 +2842,16 @@ msgstr "Account restored"
msgid "Cuentas eliminadas"
msgstr "Accounts removed"
-#: ../../../modules/web/Controllers/AccountController.php:919
+#: ../../../modules/web/Controllers/AccountController.php:918
#: ../../../modules/web/Forms/NotificationForm.php:100
msgid "Es necesaria una descripción"
msgstr "A description is needed"
-#: ../../../modules/web/Controllers/AccountController.php:927
+#: ../../../modules/web/Controllers/AccountController.php:926
msgid "Solicitante"
msgstr "Requester"
-#: ../../../modules/web/Controllers/AccountController.php:930
+#: ../../../modules/web/Controllers/AccountController.php:929
#: ../../../modules/web/Controllers/Helpers/Grid/CategoryGrid.php:106
#: ../../../modules/web/Controllers/Helpers/Grid/ClientGrid.php:105
#: ../../../modules/web/Controllers/Helpers/Grid/EventlogGrid.php:105
@@ -2837,7 +2865,7 @@ msgstr "Requester"
msgid "Descripción"
msgstr "Description"
-#: ../../../modules/web/Controllers/AccountController.php:943
+#: ../../../modules/web/Controllers/AccountController.php:942
msgid "Solicitud realizada"
msgstr "Request done"
@@ -3066,7 +3094,7 @@ msgid "Ey, esto es una DEMO!!"
msgstr "Ey, this is a DEMO!!"
#: ../../../modules/web/Controllers/ConfigBackupController.php:86
-#: ../../../modules/web/Controllers/UserPassResetController.php:173
+#: ../../../modules/web/Controllers/UserPassResetController.php:176
#: ../../../modules/web/Forms/AccountForm.php:135
#: ../../../modules/web/Forms/UserForm.php:161
msgid "Las claves no coinciden"
@@ -3951,15 +3979,11 @@ msgid "Eliminar Notificación"
msgstr "Delete Notification"
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:89
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:334
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:336
#: ../../../modules/web/themes/material-blue/views/plugin/index.inc:1
msgid "Plugins"
msgstr "Plugins"
-#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:101
-msgid "Plugin"
-msgstr "Plugin"
-
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:118
msgid "No disponible"
msgstr "Unavailable"
@@ -3973,7 +3997,7 @@ msgstr "Search for Plugin"
#. (itstool) path: action/text
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:149
#: ../../../modules/web/Controllers/Helpers/Grid/PluginGrid.php:150
-#: ../../../modules/web/Controllers/PluginController.php:120
+#: ../../../modules/web/Controllers/PluginController.php:125
#: ../../../config/actions.xml:541
msgid "Ver Plugin"
msgstr "View Plugin"
@@ -4224,13 +4248,13 @@ msgstr "Edit Profile"
msgid "Eliminar Perfil"
msgstr "Delete Profile"
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:265
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:267
#: ../../../modules/web/themes/material-blue/inc/Icons.php:58
msgid "Buscar"
msgstr "Search"
#. (itstool) path: action/text
-#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:348
+#: ../../../modules/web/Controllers/Helpers/LayoutHelper.php:350
#: ../../../modules/web/themes/material-blue/inc/Icons.php:61
#: ../../../modules/web/themes/material-blue/views/config/ldap.inc:21
#: ../../../modules/web/themes/material-blue/views/itemshow/user_profile.inc:22
@@ -4282,15 +4306,15 @@ msgstr "Value created"
msgid "Valor actualizado"
msgstr "Value updated"
-#: ../../../modules/web/Controllers/LoginController.php:101
+#: ../../../modules/web/Controllers/LoginController.php:119
msgid "Finalizar sesión"
msgstr "Logout session"
-#: ../../../modules/web/Controllers/LoginController.php:103
+#: ../../../modules/web/Controllers/LoginController.php:121
msgid "Tiempo inactivo"
msgstr "Inactive time"
-#: ../../../modules/web/Controllers/LoginController.php:104
+#: ../../../modules/web/Controllers/LoginController.php:122
msgid "Tiempo total"
msgstr "Total time"
@@ -4319,18 +4343,13 @@ msgstr "Notification created"
msgid "Notificación actualizada"
msgstr "Notification updated"
-#: ../../../modules/web/Controllers/PluginController.php:181
-#: ../../../modules/web/Controllers/PluginController.php:184
+#: ../../../modules/web/Controllers/PluginController.php:188
+#: ../../../modules/web/Controllers/PluginController.php:191
msgid "Plugin habilitado"
msgstr "Plugin enabled"
-#: ../../../modules/web/Controllers/PluginController.php:206
-#: ../../../modules/web/Controllers/PluginController.php:209
-msgid "Plugin deshabilitado"
-msgstr "Plugin disabled"
-
-#: ../../../modules/web/Controllers/PluginController.php:231
-#: ../../../modules/web/Controllers/PluginController.php:234
+#: ../../../modules/web/Controllers/PluginController.php:238
+#: ../../../modules/web/Controllers/PluginController.php:241
msgid "Plugin restablecido"
msgstr "Plugin reset"
@@ -4357,11 +4376,11 @@ msgstr "Link deleted"
msgid "Enlace creado"
msgstr "Link created"
-#: ../../../modules/web/Controllers/StatusController.php:94
+#: ../../../modules/web/Controllers/StatusController.php:93
msgid "Versión no disponible"
msgstr "Version unavailable"
-#: ../../../modules/web/Controllers/StatusController.php:142
+#: ../../../modules/web/Controllers/StatusController.php:140
msgid "Notificaciones no disponibles"
msgstr "Notifications not available"
@@ -4467,7 +4486,7 @@ msgstr "Request sent"
msgid "En breve recibirá un correo para completar la solicitud."
msgstr "You will receive an email to complete the request shortly."
-#: ../../../modules/web/Controllers/UserPassResetController.php:169
+#: ../../../modules/web/Controllers/UserPassResetController.php:172
#: ../../../modules/web/Forms/AuthTokenForm.php:101
#: ../../../modules/web/Forms/UserForm.php:157
msgid "La clave no puede estar en blanco"
@@ -4501,7 +4520,7 @@ msgstr "View Profile"
msgid "Preferencias actualizadas"
msgstr "Preferences updated"
-#: ../../../modules/web/Controllers/UserSettingsManagerController.php:89
+#: ../../../modules/web/Controllers/UserSettingsManagerController.php:92
msgid "Preferencias"
msgstr "Preferences"
diff --git a/app/modules/web/Controllers/BootstrapController.php b/app/modules/web/Controllers/BootstrapController.php
index 777b0f71..4764f4ad 100644
--- a/app/modules/web/Controllers/BootstrapController.php
+++ b/app/modules/web/Controllers/BootstrapController.php
@@ -43,6 +43,10 @@ final class BootstrapController extends SimpleControllerBase
/**
* Returns environment data
+ *
+ * @return bool
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
public function getEnvironmentAction()
{
@@ -103,6 +107,8 @@ final class BootstrapController extends SimpleControllerBase
/**
* @return bool
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
private function getAuthBasicAutologinEnabled()
{
@@ -112,6 +118,8 @@ final class BootstrapController extends SimpleControllerBase
/**
* @return string
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
private function getPublicKey()
{
diff --git a/app/modules/web/Controllers/ControllerBase.php b/app/modules/web/Controllers/ControllerBase.php
index 9488520c..dad66d74 100644
--- a/app/modules/web/Controllers/ControllerBase.php
+++ b/app/modules/web/Controllers/ControllerBase.php
@@ -28,7 +28,9 @@ defined('APP_ROOT') || die();
use DI\Container;
use Psr\Container\ContainerInterface;
+use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\FileNotFoundException;
+use SP\Core\Exceptions\SPException;
use SP\DataModel\ProfileData;
use SP\Modules\Web\Controllers\Helpers\LayoutHelper;
use SP\Modules\Web\Controllers\Traits\WebControllerTrait;
@@ -200,14 +202,16 @@ abstract class ControllerBase
/**
* Comprobar si el usuario está logado.
*
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
+ * @param bool $requireAuthCompleted
+ *
* @throws AuthException
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
- protected function checkLoggedIn()
+ protected function checkLoggedIn($requireAuthCompleted = true)
{
if ($this->session->isLoggedIn()
- && $this->session->getAuthCompleted() === true
+ && $this->session->getAuthCompleted() === $requireAuthCompleted
) {
$browser = $this->dic->get(Browser::class);
@@ -219,11 +223,37 @@ abstract class ControllerBase
}
}
- $this->checkLoggedInSession($this->session, $this->request, function ($redirect) {
- $this->router->response()
- ->redirect($redirect)
- ->send(true);
- });
+ $this->checkLoggedInSession(
+ $this->session,
+ $this->request,
+ function ($redirect) {
+ $this->router->response()
+ ->redirect($redirect)
+ ->send(true);
+ },
+ $requireAuthCompleted
+ );
+ }
+
+ /**
+ * prepareSignedUriOnView
+ *
+ * Prepares view's variables to pass in a signed URI
+ */
+ final protected function prepareSignedUriOnView()
+ {
+ $from = $this->request->analyzeString('from');
+
+ if ($from) {
+ try {
+ $this->request->verifySignature($this->configData->getPasswordSalt());
+
+ $this->view->assign('from', $from);
+ $this->view->assign('from_hash', Hash::signMessage($from, $this->configData->getPasswordSalt()));
+ } catch (SPException $e) {
+ processException($e);
+ }
+ }
}
/**
diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php
index 63d8c395..340a89cb 100644
--- a/app/modules/web/Controllers/Helpers/LayoutHelper.php
+++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php
@@ -191,7 +191,9 @@ final class LayoutHelper extends HelperBase
// Cargar los recursos de los plugins
foreach ($this->dic->get(PluginManager::class)->getLoadedPlugins() as $plugin) {
- $base = str_replace(BASE_PATH, '', $plugin->getBase());
+ $base = str_replace(APP_ROOT, '', $plugin->getBase());
+ $base .= DIRECTORY_SEPARATOR . 'public';
+
$jsResources = $plugin->getJsResources();
$cssResources = $plugin->getCssResources();
diff --git a/app/modules/web/Controllers/IndexController.php b/app/modules/web/Controllers/IndexController.php
index 535def46..ab129fee 100644
--- a/app/modules/web/Controllers/IndexController.php
+++ b/app/modules/web/Controllers/IndexController.php
@@ -41,7 +41,9 @@ final class IndexController extends ControllerBase
*/
public function indexAction()
{
- if (!$this->session->isLoggedIn()) {
+ if ($this->session->isLoggedIn() === false
+ || $this->session->getAuthCompleted() === false
+ ) {
$this->router->response()
->redirect('index.php?r=login');
} else {
diff --git a/app/modules/web/Controllers/LoginController.php b/app/modules/web/Controllers/LoginController.php
index afa459e1..74263dfc 100644
--- a/app/modules/web/Controllers/LoginController.php
+++ b/app/modules/web/Controllers/LoginController.php
@@ -25,11 +25,10 @@
namespace SP\Modules\Web\Controllers;
use SP\Core\Context\SessionContext;
-use SP\Core\Crypt\Hash;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
-use SP\Core\Exceptions\SPException;
use SP\Core\SessionUtil;
+use SP\Http\Uri;
use SP\Modules\Web\Controllers\Helpers\LayoutHelper;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Services\Auth\LoginService;
@@ -54,30 +53,34 @@ final class LoginController extends ControllerBase
try {
$loginService = $this->dic->get(LoginService::class);
- $from = $this->request->analyzeString('from');
-
- if ($from) {
- try {
- $this->request->verifySignature($this->configData->getPasswordSalt(), 'from');
-
- $loginService->setFrom($from);
- } catch (SPException $e) {
- processException($e);
- }
- }
+ $from = $this->getSignedUriFromRequest();
+ $loginService->setFrom($from);
$loginResponmse = $loginService->doLogin();
- $forward = $this->request->getForwardedFor();
+ $this->checkForwarded();
- if ($forward !== null) {
- $this->eventDispatcher->notifyEvent('login.info',
- new Event($this, EventMessage::factory()
- ->addDetail('Forwarded', $this->configData->isDemoEnabled() ? '***' : implode(',', $forward)))
- );
- }
+ $redirector = function ($route) use ($from) {
+ $uri = new Uri('index.php');
+ $uri->addParam('r', $route);
- return $this->returnJsonResponseData(['url' => $loginResponmse->getRedirect()]);
+ if ($from !== null) {
+ return $uri->addParam('from', $from)
+ ->getUriSigned($this->configData->getPasswordSalt());
+ }
+
+ return $uri->getUri();
+ };
+
+ $this->eventDispatcher->notifyEvent('login.finish',
+ new Event($this,
+ EventMessage::factory()
+ ->addData('redirect', $redirector))
+ );
+
+ return $this->returnJsonResponseData([
+ 'url' => $this->session->getTrasientKey('redirect') ?: $loginResponmse->getRedirect()
+ ]);
} catch (\Exception $e) {
processException($e);
@@ -87,12 +90,27 @@ final class LoginController extends ControllerBase
}
}
+ /**
+ * checkForwarded
+ */
+ private function checkForwarded()
+ {
+ $forward = $this->request->getForwardedFor();
+
+ if ($forward !== null) {
+ $this->eventDispatcher->notifyEvent('login.info',
+ new Event($this, EventMessage::factory()
+ ->addDetail('Forwarded', $this->configData->isDemoEnabled() ? '***' : implode(',', $forward)))
+ );
+ }
+ }
+
/**
* Logout action
*/
public function logoutAction()
{
- if ($this->session->isLoggedIn()) {
+ if ($this->session->isLoggedIn() === true) {
$inactiveTime = abs(round((time() - $this->session->getLastActivity()) / 60, 2));
$totalTime = abs(round((time() - $this->session->getStartActivity()) / 60, 2));
@@ -125,30 +143,13 @@ final class LoginController extends ControllerBase
*/
public function indexAction()
{
- if ($this->session->isLoggedIn() === true) {
- $this->router->response()
- ->redirect('index.php?r=index')
- ->send(true);
- }
-
$this->dic->get(LayoutHelper::class)
->getCustomLayout('index', 'login');
$this->view->assign('mailEnabled', $this->configData->isMailEnabled());
// $this->view->assign('updated', SessionFactory::getAppUpdated());
- $from = $this->request->analyzeString('from');
-
- if ($from) {
- try {
- $this->request->verifySignature($this->configData->getPasswordSalt());
-
- $this->view->assign('from', $from);
- $this->view->assign('from_hash', Hash::signMessage($from, $this->configData->getPasswordSalt()));
- } catch (SPException $e) {
- processException($e);
- }
- }
+ $this->prepareSignedUriOnView();
$this->view();
}
diff --git a/app/modules/web/Controllers/PluginController.php b/app/modules/web/Controllers/PluginController.php
index d1bb4b5d..eb421a29 100644
--- a/app/modules/web/Controllers/PluginController.php
+++ b/app/modules/web/Controllers/PluginController.php
@@ -74,6 +74,8 @@ final class PluginController extends ControllerBase
* getSearchGrid
*
* @return $this
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
@@ -89,6 +91,9 @@ final class PluginController extends ControllerBase
/**
* Search action
*
+ * @return bool
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
@@ -138,6 +143,8 @@ final class PluginController extends ControllerBase
*
* @param $pluginId
*
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws \SP\Repositories\NoSuchItemException
diff --git a/app/modules/web/Controllers/ResourceController.php b/app/modules/web/Controllers/ResourceController.php
index f1c9a2e5..400bcd4f 100644
--- a/app/modules/web/Controllers/ResourceController.php
+++ b/app/modules/web/Controllers/ResourceController.php
@@ -126,6 +126,8 @@ final class ResourceController extends SimpleControllerBase
/**
* @throws SPException
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
protected function initialize()
{
diff --git a/app/modules/web/Controllers/StatusController.php b/app/modules/web/Controllers/StatusController.php
index 0d320750..298eb139 100644
--- a/app/modules/web/Controllers/StatusController.php
+++ b/app/modules/web/Controllers/StatusController.php
@@ -25,7 +25,7 @@
namespace SP\Modules\Web\Controllers;
use GuzzleHttp\Client;
-use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Exception\GuzzleException;
use SP\Core\AppInfoInterface;
use SP\Core\Exceptions\CheckException;
use SP\Http\JsonResponse;
@@ -47,7 +47,6 @@ final class StatusController extends SimpleControllerBase
* @return bool
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
- * @throws \GuzzleHttp\Exception\GuzzleException
*/
public function checkReleaseAction()
{
@@ -92,7 +91,7 @@ final class StatusController extends SimpleControllerBase
}
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Versión no disponible'));
- } catch (ClientException $e) {
+ } catch (GuzzleException $e) {
processException($e);
return $this->returnJsonResponseException($e);
@@ -107,7 +106,6 @@ final class StatusController extends SimpleControllerBase
* @return bool
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
- * @throws \GuzzleHttp\Exception\GuzzleException
*/
public function checkNoticesAction()
{
@@ -140,7 +138,7 @@ final class StatusController extends SimpleControllerBase
}
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Notificaciones no disponibles'));
- } catch (ClientException $e) {
+ } catch (GuzzleException $e) {
processException($e);
return $this->returnJsonResponseException($e);
diff --git a/app/modules/web/Controllers/Traits/WebControllerTrait.php b/app/modules/web/Controllers/Traits/WebControllerTrait.php
index dc31da62..89bc7caf 100644
--- a/app/modules/web/Controllers/Traits/WebControllerTrait.php
+++ b/app/modules/web/Controllers/Traits/WebControllerTrait.php
@@ -32,6 +32,7 @@ use SP\Core\Acl\Acl;
use SP\Core\Context\ContextInterface;
use SP\Core\Context\SessionContext;
use SP\Core\Events\EventDispatcher;
+use SP\Core\Exceptions\SPException;
use SP\Core\PhpExtensionChecker;
use SP\Core\UI\Theme;
use SP\Http\Request;
@@ -90,6 +91,37 @@ trait WebControllerTrait
* @var PhpExtensionChecker
*/
protected $extensionChecker;
+ /**
+ * @var bool
+ */
+ private $setup = false;
+
+ /**
+ * Returns the signed URI component after validating its signature.
+ * This component is used for deep linking
+ *
+ * @return null|string
+ */
+ final protected function getSignedUriFromRequest()
+ {
+ if (!$this->setup) {
+ return null;
+ }
+
+ $from = $this->request->analyzeString('from');
+
+ if ($from) {
+ try {
+ $this->request->verifySignature($this->configData->getPasswordSalt(), 'from');
+ } catch (SPException $e) {
+ processException($e);
+
+ $from = null;
+ }
+ }
+
+ return $from;
+ }
/**
* @param ContainerInterface $dic
@@ -107,5 +139,7 @@ trait WebControllerTrait
$this->request = $dic->get(Request::class);
$this->acl = $dic->get(Acl::class);
$this->extensionChecker = $dic->get(PhpExtensionChecker::class);
+
+ $this->setup = true;
}
}
\ No newline at end of file
diff --git a/app/modules/web/Controllers/UserPassResetController.php b/app/modules/web/Controllers/UserPassResetController.php
index 6743d6a4..d14183eb 100644
--- a/app/modules/web/Controllers/UserPassResetController.php
+++ b/app/modules/web/Controllers/UserPassResetController.php
@@ -139,6 +139,9 @@ final class UserPassResetController extends ControllerBase
/**
* @param null $hash
+ *
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
public function resetAction($hash = null)
{
diff --git a/app/modules/web/Controllers/UserSettingsManagerController.php b/app/modules/web/Controllers/UserSettingsManagerController.php
index 72db626f..e3e62bbc 100644
--- a/app/modules/web/Controllers/UserSettingsManagerController.php
+++ b/app/modules/web/Controllers/UserSettingsManagerController.php
@@ -26,17 +26,20 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Events\Event;
+use SP\Core\Events\EventDispatcherInterface;
use SP\Core\Language;
use SP\Modules\Web\Controllers\Helpers\TabsHelper;
+use SP\Mvc\Controller\ExtensibleTabControllerInterface;
use SP\Mvc\View\Components\DataTab;
use SP\Mvc\View\Components\SelectItemAdapter;
+use SP\Mvc\View\Template;
/**
* Class UserSettingsManagerController
*
* @package web\Controllers
*/
-final class UserSettingsManagerController extends ControllerBase
+final class UserSettingsManagerController extends ControllerBase implements ExtensibleTabControllerInterface
{
/**
* @var TabsHelper
@@ -89,6 +92,38 @@ final class UserSettingsManagerController extends ControllerBase
return new DataTab(__('Preferencias'), $template);
}
+ /**
+ * @param DataTab $tab
+ */
+ public function addTab(DataTab $tab)
+ {
+ $this->tabsHelper->addTab($tab);
+ }
+
+ /**
+ * @return Template
+ */
+ public function getView(): Template
+ {
+ return $this->view;
+ }
+
+ /**
+ * @return void
+ */
+ public function displayView()
+ {
+ $this->view();
+ }
+
+ /**
+ * @return EventDispatcherInterface
+ */
+ public function getEventDispatcher(): EventDispatcherInterface
+ {
+ return $this->eventDispatcher;
+ }
+
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
diff --git a/app/modules/web/Init.php b/app/modules/web/Init.php
index f1f9c2a9..f958d6d2 100644
--- a/app/modules/web/Init.php
+++ b/app/modules/web/Init.php
@@ -183,7 +183,10 @@ final class Init extends ModuleBase
}
// Checks if the database is set up
- if (!DatabaseUtil::checkDatabaseExist($this->container->get(Database::class)->getDbHandler(), $this->configData->getDbName())) {
+ if (!DatabaseUtil::checkDatabaseExist(
+ $this->container->get(Database::class)->getDbHandler(),
+ $this->configData->getDbName())
+ ) {
$this->router->response()
->redirect('index.php?r=error/databaseError')
->send();
diff --git a/composer.json b/composer.json
index 8d2951af..0d777e8e 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,5 @@
{
- "name": "nuxsmin/syspass",
+ "name": "syspass/syspass",
"description": "PHP web based Password Manager for business and personal use.",
"homepage": "https://syspass.org",
"minimum-stability": "stable",
@@ -32,7 +32,8 @@
"ext-pdo": "*",
"ext-dom": "*",
"ext-gd": "*",
- "ext-json": "*"
+ "ext-json": "*",
+ "ext-gettext": "*"
},
"require-dev": {
"phpunit/phpunit": "^6",
diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php
index 26d85485..d4a25b07 100644
--- a/lib/SP/Bootstrap.php
+++ b/lib/SP/Bootstrap.php
@@ -40,6 +40,7 @@ use SP\Core\PhpExtensionChecker;
use SP\Http\Request;
use SP\Modules\Api\Init as InitApi;
use SP\Modules\Web\Init as InitWeb;
+use SP\Plugin\PluginManager;
use SP\Services\Api\ApiRequest;
use SP\Services\Api\JsonRpcResponse;
use SP\Services\Upgrade\UpgradeConfigService;
@@ -202,9 +203,14 @@ final class Bootstrap
$controllerClass = 'SP\\Modules\\' . ucfirst(APP_MODULE) . '\\Controllers\\' . ucfirst($controller) . 'Controller';
+ $this->initializePluginClasses();
+
if (!method_exists($controllerClass, $method)) {
logger($controllerClass . '::' . $method);
+ /** @var Response $response */
+ $response->code(404);
+
throw new RuntimeException($oops);
}
@@ -223,6 +229,11 @@ final class Bootstrap
} catch (\Exception $e) {
processException($e);
+ /** @var Response $response */
+ if ($response->status()->getCode() !== 404) {
+ $response->code(503);
+ }
+
return __($e->getMessage());
}
}
@@ -410,6 +421,18 @@ final class Bootstrap
}
}
+ /**
+ * initializePluginClasses
+ */
+ protected function initializePluginClasses()
+ {
+ $loader = require APP_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
+
+ foreach (PluginManager::getPlugins() as $name => $base) {
+ $loader->addPsr4($base['namespace'], $base['dir']);
+ }
+ }
+
/**
* @return ContainerInterface
*/
diff --git a/lib/SP/Core/Context/ContextInterface.php b/lib/SP/Core/Context/ContextInterface.php
index 64ac9705..4b4dc439 100644
--- a/lib/SP/Core/Context/ContextInterface.php
+++ b/lib/SP/Core/Context/ContextInterface.php
@@ -188,4 +188,21 @@ interface ContextInterface
* @param string $password
*/
public function setTemporaryMasterPass(string $password);
+
+ /**
+ * @param string $pluginName
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function setPluginKey(string $pluginName, string $key, $value);
+
+ /**
+ * @param string $pluginName
+ * @param string $key
+ *
+ * @return mixed
+ */
+ public function getPluginKey(string $pluginName, string $key);
}
\ No newline at end of file
diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php
index 217a33c9..e5ff4f86 100644
--- a/lib/SP/Core/Context/SessionContext.php
+++ b/lib/SP/Core/Context/SessionContext.php
@@ -39,7 +39,7 @@ use SP\Services\User\UserLoginResponse;
final class SessionContext extends ContextBase
{
const MAX_SID_TIME = 120;
-
+
private static $isReset = false;
private static $isLocked = false;
@@ -549,4 +549,39 @@ final class SessionContext extends ContextBase
$this->setContextReference($_SESSION);
}
+
+ /**
+ * @param string $ctxKeyName
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function setPluginKey(string $ctxKeyName, string $key, $value)
+ {
+ /** @var ContextCollection $ctxKey */
+ $ctxKey = $this->getContextKey($ctxKeyName, new ContextCollection());
+
+ $this->setContextKey($ctxKeyName, $ctxKey->set($key, $value));
+
+ return $value;
+ }
+
+ /**
+ * @param string $ctxKeyName
+ * @param string $key
+ *
+ * @return mixed
+ */
+ public function getPluginKey(string $ctxKeyName, string $key)
+ {
+ /** @var ContextCollection $ctxKey */
+ $ctxKey = $this->getContextKey($ctxKeyName);
+
+ if ($ctxKey !== null) {
+ return $ctxKey->get($key);
+ }
+
+ return null;
+ }
}
diff --git a/lib/SP/Core/Context/StatelessContext.php b/lib/SP/Core/Context/StatelessContext.php
index c3c015c1..5652e8e2 100644
--- a/lib/SP/Core/Context/StatelessContext.php
+++ b/lib/SP/Core/Context/StatelessContext.php
@@ -269,4 +269,37 @@ final class StatelessContext extends ContextBase
{
$this->setTrasientKey('_tempmasterpass', $password);
}
+
+ /**
+ * @param string $pluginName
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function setPluginKey(string $pluginName, string $key, $value)
+ {
+ $ctxKey = $this->getContextKey('plugins');
+
+ $ctxKey[$pluginName][$key] = $value;
+
+ return $value;
+ }
+
+ /**
+ * @param string $pluginName
+ * @param string $key
+ *
+ * @return mixed
+ */
+ public function getPluginKey(string $pluginName, string $key)
+ {
+ $ctxKey = $this->getContextKey('plugins');
+
+ if (isset($ctxKey[$pluginName][$key])) {
+ return $ctxKey[$pluginName][$key];
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Core/Events/Event.php b/lib/SP/Core/Events/Event.php
index 80edc9ed..fd9983e5 100644
--- a/lib/SP/Core/Events/Event.php
+++ b/lib/SP/Core/Events/Event.php
@@ -25,6 +25,7 @@
namespace SP\Core\Events;
use InvalidArgumentException;
+use SP\Core\Exceptions\InvalidClassException;
/**
* Class Event
@@ -61,10 +62,24 @@ final class Event
}
/**
+ * @param null $type
+ *
* @return object
+ * @throws InvalidClassException
*/
- public function getSource()
+ public function getSource($type = null)
{
+ if ($type !== null
+ && ($source = get_class($this->source)) !== $type
+ && !is_subclass_of($this->source, $type)
+ ) {
+ throw new InvalidClassException(
+ 'Source type mismatch',
+ InvalidClassException::ERROR,
+ sprintf('Source: %s - Expected: %s', $source, $type)
+ );
+ }
+
return $this->source;
}
diff --git a/lib/SP/Core/Events/EventDispatcherBase.php b/lib/SP/Core/Events/EventDispatcherBase.php
index 771a733f..98b88092 100644
--- a/lib/SP/Core/Events/EventDispatcherBase.php
+++ b/lib/SP/Core/Events/EventDispatcherBase.php
@@ -111,12 +111,16 @@ abstract class EventDispatcherBase implements EventDispatcherInterface
public function notifyEvent($eventType, Event $event)
{
foreach ($this->observers as $observer) {
- $events = $observer->getEventsString();
+ if (method_exists($observer, 'getEventsString')) {
+ $events = $observer->getEventsString();
- if (!empty($events)
- && ($events === '*' || preg_match('/' . $events . '/i', $eventType))
- ) {
- // FIXME: update receivers Event
+ if (!empty($events)
+ && ($events === '*' || preg_match('/' . $events . '/i', $eventType))
+ ) {
+ // FIXME: update receivers Event
+ $observer->updateEvent($eventType, $event);
+ }
+ } else {
$observer->updateEvent($eventType, $event);
}
}
diff --git a/lib/SP/Html/Minify.php b/lib/SP/Html/Minify.php
index e89dfe03..1beee474 100644
--- a/lib/SP/Html/Minify.php
+++ b/lib/SP/Html/Minify.php
@@ -220,7 +220,7 @@ final class Minify
$this->addFile($filename, $minify);
}
} else {
- throw new \RuntimeException('Invalid string format');
+ $this->addFile($files, $minify);
}
return $this;
diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php
index df21d811..4d6c454f 100644
--- a/lib/SP/Http/Request.php
+++ b/lib/SP/Http/Request.php
@@ -374,8 +374,11 @@ final class Request
public function verifySignature(string $key, string $param = null)
{
$result = false;
+ $hash = $this->params->get('h');
- if (($hash = $this->params->get('h')) !== null) {
+ if ($hash !== null) {
+ // Strips out the hash param from the URI to get the
+ // route which will be checked against the computed HMAC
if ($param === null) {
$uri = str_replace('&h=' . $hash, '', $this->request->uri());
$uri = substr($uri, strpos($uri, '?') + 1);
diff --git a/lib/SP/Mvc/Controller/ControllerTrait.php b/lib/SP/Mvc/Controller/ControllerTrait.php
index bfabd6e7..a3b8a608 100644
--- a/lib/SP/Mvc/Controller/ControllerTrait.php
+++ b/lib/SP/Mvc/Controller/ControllerTrait.php
@@ -25,6 +25,7 @@
namespace SP\Mvc\Controller;
use SP\Core\Context\ContextInterface;
+use SP\Core\Context\SessionContext;
use SP\Core\Exceptions\SPException;
use SP\Http\Json;
use SP\Http\JsonResponse;
@@ -53,13 +54,19 @@ trait ControllerTrait
/**
* Comprobar si la sesión está activa
*
- * @param ContextInterface $context
- * @param Request $request
- * @param \Closure $onRedirect
+ * @param SessionContext $context
+ * @param Request $request
+ * @param \Closure $onRedirect
+ * @param bool $requireAuthCompleted
*/
- protected function checkLoggedInSession(ContextInterface $context, Request $request, \Closure $onRedirect)
+ protected function checkLoggedInSession(SessionContext $context,
+ Request $request,
+ \Closure $onRedirect,
+ $requireAuthCompleted = true)
{
- if (!$context->isLoggedIn()) {
+ if ($context->isLoggedIn() === false
+ || $context->getAuthCompleted() !== $requireAuthCompleted
+ ) {
if ($request->isJson()) {
$jsonResponse = new JsonResponse(__u('La sesión no se ha iniciado o ha caducado'));
$jsonResponse->setStatus(10);
@@ -69,6 +76,9 @@ trait ControllerTrait
Util::logout();
} else {
try {
+ // Analyzes if there is any direct route within the URL
+ // then it computes the route HMAC to build a signed URI
+ // which would be used during logging in
$route = $request->analyzeString('r');
$hash = $request->analyzeString('h');
diff --git a/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php b/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php
new file mode 100644
index 00000000..43cd28da
--- /dev/null
+++ b/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php
@@ -0,0 +1,52 @@
+.
+ */
+
+namespace SP\Mvc\Controller;
+
+
+use SP\Core\Events\EventDispatcherInterface;
+use SP\Mvc\View\Template;
+
+/**
+ * Interface ExtensibleController
+ *
+ * @package SP\Mvc\Controller
+ */
+interface ExtensibleControllerInterface
+{
+ /**
+ * @return Template
+ */
+ public function getView(): Template;
+
+ /**
+ * @return void
+ */
+ public function displayView();
+
+ /**
+ * @return EventDispatcherInterface
+ */
+ public function getEventDispatcher(): EventDispatcherInterface;
+}
\ No newline at end of file
diff --git a/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php b/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php
new file mode 100644
index 00000000..38ec2977
--- /dev/null
+++ b/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php
@@ -0,0 +1,40 @@
+.
+ */
+
+namespace SP\Mvc\Controller;
+
+use SP\Mvc\View\Components\DataTab;
+
+/**
+ * Interface ExtensibleTabController
+ *
+ * @package SP\Mvc\Controller
+ */
+interface ExtensibleTabControllerInterface extends ExtensibleControllerInterface
+{
+ /**
+ * @param DataTab $tab
+ */
+ public function addTab(DataTab $tab);
+}
\ No newline at end of file
diff --git a/lib/SP/Mvc/View/Template.php b/lib/SP/Mvc/View/Template.php
index e12218d5..e001a692 100644
--- a/lib/SP/Mvc/View/Template.php
+++ b/lib/SP/Mvc/View/Template.php
@@ -112,10 +112,14 @@ final class Template
*/
private function checkTemplate($template, $base = null)
{
- if (null === $base && null === $this->base) {
+ $base = null !== $base ? $base : (null !== $this->base ? $this->base : null);
+
+ if ($base === null) {
$templateFile = $this->theme->getViewsPath() . DIRECTORY_SEPARATOR . $template . self::TEMPLATE_EXTENSION;
+ } elseif (is_dir($base)) {
+ $templateFile = $base . DIRECTORY_SEPARATOR . $template . self::TEMPLATE_EXTENSION;
} else {
- $templateFile = $this->theme->getViewsPath() . DIRECTORY_SEPARATOR . (null === $base ? $this->base : $base) . DIRECTORY_SEPARATOR . $template . self::TEMPLATE_EXTENSION;
+ $templateFile = $this->theme->getViewsPath() . DIRECTORY_SEPARATOR . $base . DIRECTORY_SEPARATOR . $template . self::TEMPLATE_EXTENSION;
}
if (!is_readable($templateFile)) {
@@ -338,7 +342,7 @@ final class Template
public function render()
{
if (count($this->templates) === 0) {
- throw new FileNotFoundException(__u('La plantilla no contiene archivos'));
+ throw new FileNotFoundException(__('La plantilla no contiene archivos'));
}
extract($this->vars, EXTR_SKIP);
diff --git a/lib/SP/Plugin/PluginBase.php b/lib/SP/Plugin/PluginBase.php
index 8eb9d93b..b069a0f2 100644
--- a/lib/SP/Plugin/PluginBase.php
+++ b/lib/SP/Plugin/PluginBase.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,6 +24,9 @@
namespace SP\Plugin;
+use Psr\Container\ContainerInterface;
+use SP\Services\Plugin\PluginService;
+
/**
* Class PluginBase
*
@@ -51,13 +54,20 @@ abstract class PluginBase implements PluginInterface
* @var int
*/
protected $enabled;
+ /**
+ * @var PluginService
+ */
+ private $pluginService;
/**
* PluginBase constructor.
+ *
+ * @param ContainerInterface $dic
*/
- public final function __construct()
+ public final function __construct(ContainerInterface $dic)
{
- $this->init();
+ $this->pluginService = $dic->get(PluginService::class);
+ $this->init($dic);
}
/**
@@ -76,14 +86,6 @@ abstract class PluginBase implements PluginInterface
$this->type = $type;
}
- /**
- * @return string
- */
- public function getBase()
- {
- return $this->base;
- }
-
/**
* @return string
*/
@@ -100,14 +102,6 @@ abstract class PluginBase implements PluginInterface
return $this->data;
}
- /**
- * @param mixed $data
- */
- public function setData($data)
- {
- $this->data = $data;
- }
-
/**
* @return int
*/
@@ -124,6 +118,19 @@ abstract class PluginBase implements PluginInterface
$this->enabled = (int)$enabled;
}
+ /**
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Repositories\NoSuchItemException
+ */
+ final public function saveData()
+ {
+ $pluginData = $this->pluginService->getByName($this->getName());
+ $pluginData->setData(serialize($this->data));
+
+ return $this->pluginService->update($pluginData);
+ }
+
/**
* Establecer las locales del plugin
*/
@@ -135,4 +142,12 @@ abstract class PluginBase implements PluginInterface
bindtextdomain($name, $locales);
bind_textdomain_codeset($name, 'UTF-8');
}
+
+ /**
+ * @return string
+ */
+ public function getBase()
+ {
+ return $this->base;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Plugin/PluginEventReceiver.php b/lib/SP/Plugin/PluginEventReceiver.php
index 6171124e..fc04e8c9 100644
--- a/lib/SP/Plugin/PluginEventReceiver.php
+++ b/lib/SP/Plugin/PluginEventReceiver.php
@@ -24,6 +24,7 @@
namespace SP\Plugin;
+use Psr\Container\ContainerInterface;
use SP\Core\Events\Event;
use SplObserver;
@@ -36,8 +37,10 @@ interface PluginEventReceiver extends SplObserver
{
/**
* Inicialización del observador
+ *
+ * @param ContainerInterface $dic
*/
- public function init();
+ public function init(ContainerInterface $dic);
/**
* Evento de actualización
diff --git a/lib/SP/Plugin/PluginInterface.php b/lib/SP/Plugin/PluginInterface.php
index 90a78eaf..a4d4d1c9 100644
--- a/lib/SP/Plugin/PluginInterface.php
+++ b/lib/SP/Plugin/PluginInterface.php
@@ -24,6 +24,8 @@
namespace SP\Plugin;
+use SP\DataModel\PluginData;
+
/**
* Interface PluginInterface
*
@@ -86,9 +88,9 @@ interface PluginInterface extends PluginEventReceiver
public function getData();
/**
- * @param mixed $data
+ * @param PluginData $pluginData
*/
- public function setData($data);
+ public function onLoadData(PluginData $pluginData);
/**
* @return int
diff --git a/lib/SP/Plugin/PluginManager.php b/lib/SP/Plugin/PluginManager.php
index 75e0c984..9a4f8a22 100644
--- a/lib/SP/Plugin/PluginManager.php
+++ b/lib/SP/Plugin/PluginManager.php
@@ -25,12 +25,16 @@
namespace SP\Plugin;
use ReflectionClass;
+use SP\Bootstrap;
use SP\Core\Context\ContextInterface;
use SP\Core\Events\Event;
use SP\Core\Events\EventDispatcher;
use SP\Core\Events\EventMessage;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
use SP\DataModel\PluginData;
use SP\Repositories\NoSuchItemException;
+use SP\Services\Install\Installer;
use SP\Services\Plugin\PluginService;
/**
@@ -40,6 +44,10 @@ use SP\Services\Plugin\PluginService;
*/
final class PluginManager
{
+ /**
+ * @var array
+ */
+ private static $pluginsAvailable;
/**
* @var array Plugins habilitados
*/
@@ -77,6 +85,39 @@ final class PluginManager
$this->pluginService = $pluginService;
$this->context = $context;
$this->eventDispatcher = $eventDispatcher;
+
+ self::$pluginsAvailable = self::getPlugins();
+ }
+
+ /**
+ * Devuelve la lista de Plugins disponibles em el directorio
+ *
+ * @return array
+ */
+ public static function getPlugins()
+ {
+ $dir = dir(PLUGINS_PATH);
+ $plugins = [];
+
+ if ($dir) {
+ while (false !== ($entry = $dir->read())) {
+ $pluginDir = PLUGINS_PATH . DIRECTORY_SEPARATOR . $entry;
+ $pluginFile = $pluginDir . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Plugin.php';
+
+ if (strpos($entry, '.') === false
+ && is_dir($pluginDir)
+ && file_exists($pluginFile)
+ ) {
+ logger(sprintf('Plugin found: %s', $pluginDir));
+
+ $plugins[$entry] = require $pluginDir . DIRECTORY_SEPARATOR . 'base.php';
+ }
+ }
+
+ $dir->close();
+ }
+
+ return $plugins;
}
/**
@@ -88,35 +129,200 @@ final class PluginManager
*/
public function getPluginInfo($name)
{
- $name = ucfirst($name);
+ if (isset(self::$pluginsAvailable[$name])) {
+ return $this->loadPluginClass(
+ $name,
+ self::$pluginsAvailable[$name]['namespace']
+ );
+ }
- $pluginClass = 'Plugins\\' . $name . '\\' . $name . 'Plugin';
+ return null;
+ }
+
+ /**
+ * Cargar un plugin
+ *
+ * @param string $name Nombre del plugin
+ * @param string $namespace
+ *
+ * @return PluginInterface
+ */
+ public function loadPluginClass(string $name, string $namespace)
+ {
+ $name = ucfirst($name);
if (isset($this->loadedPlugins[$name])) {
return $this->loadedPlugins[$name];
}
try {
- $reflectionClass = new \ReflectionClass($pluginClass);
+ $class = $namespace . 'Plugin';
+ $reflectionClass = new ReflectionClass($class);
- /** @var PluginBase $plugin */
- $plugin = $reflectionClass->newInstance();
+ /** @var PluginInterface $plugin */
+ $plugin = $reflectionClass->newInstance(Bootstrap::getContainer());
- $this->loadedPlugins[$name] = $plugin;
+ // Do not load plugin's data if not compatible.
+ // Just return the plugin instance before disabling it
+ if (self::checkCompatibility($plugin) === false) {
+ $this->eventDispatcher->notifyEvent('plugin.load.error',
+ new Event($this, EventMessage::factory()
+ ->addDescription(sprintf(__('Versión de plugin no compatible (%s)'), implode('.', $plugin->getVersion()))))
+ );
- return $plugin;
- } catch (\ReflectionException $e) {
+ $this->disabledPlugins[] = $name;
+
+ return $plugin;
+ }
+
+ $pluginData = $this->pluginService->getByName($name);
+
+ if ($pluginData->getEnabled() === 1) {
+ $plugin->onLoadData($pluginData);
+
+ return $plugin;
+ } else {
+ $this->disabledPlugins[] = $name;
+ }
+ } catch (\Exception $e) {
processException($e);
$this->eventDispatcher->notifyEvent('exception',
new Event($e, EventMessage::factory()
- ->addDescription(sprintf(__('No es posible cargar el plugin "%s"'), $name)))
+ ->addDescription(sprintf(__('No es posible cargar el plugin "%s"'), $name))
+ ->addDescription($e->getMessage())
+ ->addDetail(__u('Plugin'), $name))
);
}
return null;
}
+ /**
+ * @param PluginInterface $plugin
+ *
+ * @return bool
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws QueryException
+ */
+ public function checkCompatibility(PluginInterface $plugin)
+ {
+ $pluginVersion = implode('.', $plugin->getCompatibleVersion());
+ $appVersion = implode('.', array_slice(Installer::VERSION, 0, 2));
+
+ if (version_compare($pluginVersion, $appVersion) === -1) {
+ $this->pluginService->toggleEnabledByName($plugin->getName(), false);
+
+ $this->eventDispatcher->notifyEvent('edit.plugin.disable',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Plugin deshabilitado'), $plugin->getName()))
+ );
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Loads the available and enabled plugins
+ *
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function loadPlugins()
+ {
+ $available = array_keys(self::$pluginsAvailable);
+ $processed = [];
+
+ // Process registered plugins in the database
+ foreach ($this->pluginService->getAll() as $plugin) {
+ $in = in_array($plugin->getName(), $available, true);
+
+ if ($in === true) {
+ if ($plugin->getEnabled() === 1) {
+ $this->load($plugin->getName());
+ }
+
+ if ($plugin->getAvailable() === 0) {
+ $this->pluginService->toggleAvailable($plugin->getId(), true);
+
+ $this->eventDispatcher->notifyEvent('edit.plugin.available',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Plugin disponible'), $plugin->getName()))
+ );
+
+ $this->load($plugin->getName());
+ }
+ } else {
+ $this->pluginService->toggleAvailable($plugin->getId(), false);
+
+ $this->eventDispatcher->notifyEvent('edit.plugin.unavailable',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Plugin no disponible'), $plugin->getName()))
+ );
+ }
+
+ $processed[] = $plugin->getName();
+ }
+
+ // Search for available plugins and not registered in the database
+ foreach (array_diff($available, $processed) as $plugin) {
+ $this->registerPlugin($plugin);
+
+ $this->load($plugin);
+ }
+ }
+
+ /**
+ * @param string $pluginName
+ */
+ private function load(string $pluginName)
+ {
+ $plugin = $this->loadPluginClass(
+ $pluginName,
+ self::$pluginsAvailable[$pluginName]['namespace']
+ );
+
+ if ($plugin !== null) {
+ logger(sprintf('Plugin loaded: %s', $pluginName));
+
+ $this->eventDispatcher->notifyEvent('plugin.load',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Plugin cargado'), $pluginName))
+ );
+
+ $this->loadedPlugins[$pluginName] = $plugin;
+
+ $this->eventDispatcher->attach($plugin);
+ }
+ }
+
+ /**
+ * @param string $name
+ *
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ private function registerPlugin(string $name)
+ {
+ $pluginData = new PluginData();
+ $pluginData->setName($name);
+ $pluginData->setEnabled(false);
+
+ $this->pluginService->create($pluginData);
+
+ $this->eventDispatcher->notifyEvent('create.plugin',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Nuevo Plugin'))
+ ->addDetail(__u('Nombre'), $name)
+ ));
+
+ $this->disabledPlugins[] = $name;
+ }
+
/**
* Comprobar disponibilidad de plugins habilitados
*
@@ -127,6 +333,11 @@ final class PluginManager
foreach ($this->getEnabledPlugins() as $plugin) {
if (!in_array($plugin, $this->loadedPlugins)) {
$this->pluginService->toggleAvailableByName($plugin, false);
+
+ $this->eventDispatcher->notifyEvent('edit.plugin.unavailable',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Plugin deshabilitado'), $plugin->getName()))
+ );
}
}
}
@@ -153,113 +364,6 @@ final class PluginManager
return $this->enabledPlugins;
}
- /**
- * Cargar los Plugins disponibles
- */
- public function loadPlugins()
- {
- $classLoader = new \SplClassLoader('Plugins', PLUGINS_PATH);
- $classLoader->register();
-
- foreach ($this->getPlugins() as $name) {
- if (($plugin = $this->loadPlugin($name)) !== null) {
- logger('Plugin loaded: ' . $name);
-
- $this->eventDispatcher->attach($plugin);
- }
- }
- }
-
- /**
- * Devuelve la lista de Plugins disponibles em el directorio
- *
- * @return array
- */
- public function getPlugins()
- {
- $pluginDirH = opendir(PLUGINS_PATH);
- $plugins = [];
-
- if ($pluginDirH) {
- while (false !== ($entry = readdir($pluginDirH))) {
- $pluginDir = PLUGINS_PATH . DIRECTORY_SEPARATOR . $entry;
-
- if (strpos($entry, '.') === false
- && is_dir($pluginDir)
- && file_exists($pluginDir . DIRECTORY_SEPARATOR . $entry . 'Plugin.php')
- ) {
- $plugins[] = $entry;
- }
- }
-
- closedir($pluginDirH);
- }
-
- return $plugins;
- }
-
- /**
- * Cargar un plugin
- *
- * @param string $name Nombre del plugin
- *
- * @return PluginInterface
- */
- public function loadPlugin($name)
- {
- $name = ucfirst($name);
-
- if (isset($this->loadedPlugins[$name])) {
- return $this->loadedPlugins[$name];
- }
-
- try {
- $pluginClass = 'Plugins\\' . $name . '\\' . $name . 'Plugin';
-
- $reflectionClass = new ReflectionClass($pluginClass);
-
- /** @var PluginInterface $plugin */
- $plugin = $reflectionClass->newInstance();
-
- try {
- $pluginData = $this->pluginService->getByName($plugin);
-
- if ($pluginData->getEnabled() === 1) {
- if (!empty($pluginData->getData())) {
- $pluginData->setData(unserialize($pluginData->getData()));
- }
-
- return $plugin;
- } else {
- $this->disabledPlugins[] = $name;
- }
- } catch (NoSuchItemException $noSuchItemException) {
- $pluginData = new PluginData();
- $pluginData->setName($name);
- $pluginData->setEnabled(0);
-
- $this->pluginService->create($pluginData);
-
- $this->eventDispatcher->notifyEvent('create.plugin',
- new Event($this, EventMessage::factory()
- ->addDescription(__u('Nuevo Plugin'))
- ->addDetail(__u('Nombre'), $name)
- ));
-
- $this->disabledPlugins[] = $name;
- }
- } catch (\Exception $e) {
- processException($e);
-
- $this->eventDispatcher->notifyEvent('exception',
- new Event($e, EventMessage::factory()
- ->addDescription(sprintf(__('No es posible cargar el plugin "%s"'), $name)))
- );
- }
-
- return null;
- }
-
/**
* Devolver los plugins cargados
*
diff --git a/lib/SP/Providers/Log/DatabaseLogHandler.php b/lib/SP/Providers/Log/DatabaseLogHandler.php
index e1aa36a5..2faebe03 100644
--- a/lib/SP/Providers/Log/DatabaseLogHandler.php
+++ b/lib/SP/Providers/Log/DatabaseLogHandler.php
@@ -66,6 +66,7 @@ final class DatabaseLogHandler extends Provider implements EventReceiver
*
*
* @return void
+ * @throws \SP\Core\Exceptions\InvalidClassException
* @since 5.1.0
*/
public function update(SplSubject $subject)
@@ -78,6 +79,8 @@ final class DatabaseLogHandler extends Provider implements EventReceiver
*
* @param string $eventType Nombre del evento
* @param Event $event Objeto del evento
+ *
+ * @throws \SP\Core\Exceptions\InvalidClassException
*/
public function updateEvent($eventType, Event $event)
{
diff --git a/lib/SP/Providers/Log/LogInterface.php b/lib/SP/Providers/Log/LogInterface.php
index 04082192..bed56144 100644
--- a/lib/SP/Providers/Log/LogInterface.php
+++ b/lib/SP/Providers/Log/LogInterface.php
@@ -56,6 +56,7 @@ interface LogInterface
'show.authToken',
'clear.eventlog',
'clear.track',
- 'unlock.track'
+ 'unlock.track',
+ 'plugin.load.error'
];
}
\ No newline at end of file
diff --git a/lib/SP/Services/Auth/LoginService.php b/lib/SP/Services/Auth/LoginService.php
index 6bd830d9..494a8e1f 100644
--- a/lib/SP/Services/Auth/LoginService.php
+++ b/lib/SP/Services/Auth/LoginService.php
@@ -386,7 +386,8 @@ final class LoginService extends Service
}
$this->eventDispatcher->notifyEvent('login.session.load',
- new Event($this, EventMessage::factory()->addDetail(__u('Usuario'), $userLoginResponse->getLogin()))
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Usuario'), $userLoginResponse->getLogin()))
);
}
diff --git a/lib/SP/Util/ErrorUtil.php b/lib/SP/Util/ErrorUtil.php
index 233d94c9..0ee0cd7f 100644
--- a/lib/SP/Util/ErrorUtil.php
+++ b/lib/SP/Util/ErrorUtil.php
@@ -54,36 +54,22 @@ final class ErrorUtil
* @param \SP\Mvc\View\Template $view
* @param \Exception $e
* @param string $replace Template replacement
+ * @param bool $render
*/
- public static function showExceptionInView(Template $view, \Exception $e, $replace = null)
- {
- switch (get_class($e)) {
- case UpdatedMasterPassException::class:
- self::showErrorInView($view, self::ERR_UPDATE_MPASS, $replace);
- break;
- case UnauthorizedPageException::class:
- self::showErrorInView($view, self::ERR_PAGE_NO_PERMISSION, $replace);
- break;
- case AccountPermissionException::class:
- self::showErrorInView($view, self::ERR_ACCOUNT_NO_PERMISSION, $replace);
- break;
- default;
- self::showErrorInView($view, self::ERR_EXCEPTION, $replace);
- }
- }
-
- /**
- * Establecer la plantilla de error con el código indicado.
- *
- * @param \SP\Mvc\View\Template $view
- * @param int $type int con el tipo de error
- * @param string $replace Template replacement
- */
- public static function showErrorInView(Template $view, $type, $replace = null)
+ public static function showExceptionInView(Template $view,
+ \Exception $e,
+ $replace = null,
+ $render = true)
{
if ($replace === null) {
$view->resetTemplates();
- $view->resetContentTemplates();
+
+ if ($view->hashContentTemplates()) {
+ $view->resetContentTemplates();
+ $view->addContentTemplate('error', Template::PARTIALS_DIR);
+ } else {
+ $view->addTemplate('error', Template::PARTIALS_DIR);
+ }
} else {
if ($view->hashContentTemplates()) {
$view->removeContentTemplate($replace);
@@ -94,6 +80,30 @@ final class ErrorUtil
}
}
+ switch (get_class($e)) {
+ case UpdatedMasterPassException::class:
+ self::showErrorInView($view, self::ERR_UPDATE_MPASS, $render);
+ break;
+ case UnauthorizedPageException::class:
+ self::showErrorInView($view, self::ERR_PAGE_NO_PERMISSION, $render);
+ break;
+ case AccountPermissionException::class:
+ self::showErrorInView($view, self::ERR_ACCOUNT_NO_PERMISSION, $render);
+ break;
+ default;
+ self::showErrorInView($view, self::ERR_EXCEPTION, $render);
+ }
+ }
+
+ /**
+ * Establecer la plantilla de error con el código indicado.
+ *
+ * @param \SP\Mvc\View\Template $view
+ * @param int $type int con el tipo de error
+ * @param bool $render
+ */
+ public static function showErrorInView(Template $view, $type, $render = true)
+ {
$error = self::getErrorTypes($type);
$view->append('errors',
@@ -103,15 +113,15 @@ final class ErrorUtil
'hint' => $error['hint']
]);
- try {
- echo $view->render();
- } catch (FileNotFoundException $e) {
- processException($e);
+ if ($render) {
+ try {
+ echo $view->render();
+ } catch (FileNotFoundException $e) {
+ processException($e);
- echo $e->getMessage();
+ echo $e->getMessage();
+ }
}
-
- die();
}
/**
diff --git a/lib/SP/Util/Util.php b/lib/SP/Util/Util.php
index 158aa3e7..d57588aa 100644
--- a/lib/SP/Util/Util.php
+++ b/lib/SP/Util/Util.php
@@ -209,38 +209,45 @@ final class Util
/**
* Cast an object to another class, keeping the properties, but changing the methods
*
- * @param string $dstClass Class name
+ * @param string $dstClass Destination class name
* @param string|object $serialized
- * @param string $srcClass Nombre de la clase serializada
+ * @param string $srcClass Old class name for removing from private methods
*
* @return mixed
- * @link http://blog.jasny.net/articles/a-dark-corner-of-php-class-casting/
*/
public static function unserialize($dstClass, $serialized, $srcClass = null)
{
if (!is_object($serialized)) {
- preg_match('/^O:\d+:"(?P[^"]++)"/', $serialized, $matches);
+ $match = preg_match_all('/O:\d+:"(?P[^"]++)"/', $serialized, $matches);
- if (class_exists($matches['class'])
- && $matches['class'] === $dstClass
- ) {
- return unserialize($serialized);
+ $process = false;
+
+ if ($match) {
+ foreach ($matches['class'] as $class) {
+ if (!class_exists($class)
+ || $class !== $dstClass
+ ) {
+ $process = true;
+ }
+ }
+
+ if ($process === false) {
+ return unserialize($serialized);
+ }
}
- // Si se indica la clase origen, se elimina el nombre
- // de la clase en los métodos privados
- if ($srcClass !== null) {
- $serializedOut = preg_replace_callback(
- '/:\d+:"\x00' . preg_quote($srcClass, '/') . '\x00(\w+)"/',
- function ($matches) {
- return ':' . strlen($matches[1]) . ':"' . $matches[1] . '"';
- },
- $serialized);
+ // Serialized data needs to be processed to change the class name
+ if ($process === true) {
+ // If source class is set, it will try to clean up the class name from private methods
+ if ($srcClass !== null) {
+ $serialized = preg_replace_callback(
+ '/:\d+:"\x00' . preg_quote($srcClass, '/') . '\x00(\w+)"/',
+ function ($matches) {
+ return ':' . strlen($matches[1]) . ':"' . $matches[1] . '"';
+ },
+ $serialized);
+ }
- return self::castToClass($serializedOut, $dstClass);
- }
-
- if ($matches['class'] !== $dstClass) {
return self::castToClass($serialized, $dstClass);
}
}
@@ -251,20 +258,18 @@ final class Util
/**
* Cast an object to another class
*
- * @param $object
+ * @param $cast
* @param $class
*
* @return mixed
*/
- public static function castToClass($object, $class)
+ public static function castToClass($cast, $class)
{
- // should avoid '__PHP_Incomplete_Class'?
+ // TODO: should avoid '__PHP_Incomplete_Class'?
- if (is_object($object)) {
- return unserialize(preg_replace('/^O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', serialize($object)));
- }
+ $cast = is_object($cast) ? serialize($cast) : $cast;
- return unserialize(preg_replace('/^O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', $object));
+ return unserialize(preg_replace('/O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', $cast));
}
/**
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index 8f360844..bf28c0c5 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -1351,11 +1351,28 @@ sysPass.Actions = function (log) {
toggle: function ($obj) {
log.info("plugin:enable");
- tabs.save($obj, function () {
- // Recargar para cargar/descargar el plugin
- setTimeout(function () {
- sysPassApp.util.redirect("index.php");
- }, 2000);
+ tabs.state.update($obj);
+
+ const itemId = $obj.data("item-id");
+
+ const opts = sysPassApp.requests.getRequestOpts();
+ opts.url = ajaxUrl.entrypoint;
+ opts.method = "get";
+ opts.data = {
+ r: $obj.data("action-route") + "/" + itemId,
+ sk: sysPassApp.sk.get(),
+ isAjax: 1
+ };
+
+ sysPassApp.requests.getActionCall(opts, function (json) {
+ sysPassApp.msg.out(json);
+
+ if (json.status === 0) {
+ // Recargar para cargar/descargar el plugin
+ setTimeout(function () {
+ sysPassApp.util.redirect("index.php");
+ }, 2000);
+ }
});
},
reset: function ($obj) {
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index 42bed938..09deaefa 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -42,14 +42,15 @@ var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"/?r="+a.data("act
d.data=a.serialize());sysPassApp.requests.getActionCall(d,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")+"/"+c})})},c=''+sysPassApp.config.LANG[48]+"
";mdlDialog().show({text:c,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();b(0)}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();b(1)}}})},delete:function(a){d.info("link:delete");var b=''+
sysPassApp.config.LANG[12]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=a.data("item-id");var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route")+"/"+b;sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")+
"/"+a.data("account-id")})})}}})},refresh:function(a){d.info("link:refresh");g.state.update(a);var b=a.data("item-id"),c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+b,sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);0===b.status&&((b=a.data("action-next"))?f({r:b+"/"+a.data("account-id")}):f({r:g.state.tab.route,tabIndex:g.state.tab.index}))})}},eventlog:{clear:function(a){var b=''+
-sysPassApp.config.LANG[20]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}},ajaxUrl:e,plugin:{toggle:function(a){d.info("plugin:enable");g.save(a,function(){setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){d.info("plugin:reset");var b=''+
-sysPassApp.config.LANG[58]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},search:function(a){d.info("plugin:search");m.search(a)},show:function(a){d.info("plugin:show");t.show(a)},save:function(a){d.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+
-"?r="+a.data("route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){d.info("plugin:nav");m.nav(a)}},notification:{check:function(a){d.info("notification:check");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);
-0===b.status&&f({r:a.data("action-next")});sysPassApp.sk.set(b.csrf)})},search:function(a){d.info("notification:search");m.search(a)},show:function(a){d.info("notification:show");t.show(a)},save:function(a){d.info("notification:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},delete:function(a){d.info("notification:delete");
-m.delete(a,function(b){var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.method="get";c.data={r:a.data("action-route")+(0===b.length?"/"+a.data("item-id"):""),items:b,sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);f({r:a.data("action-next")})})})},getActive:function(){d.info("notification:getActive");var a=sysPassApp.requests.getRequestOpts();a.url=e.entrypoint;a.method="get";a.data={r:"items/notifications",sk:sysPassApp.sk.get(),
-isAjax:1};sysPassApp.requests.getActionCall(a,function(a){return a})},nav:function(a){d.info("eventlog:nav");m.nav(a)}},wiki:{show:function(a){d.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,function(a){0!==a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){d.info("items:get");var b=a[0].selectize;
-b.clearOptions();b.load(function(c){var d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint;d.method="get";d.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};sysPassApp.requests.getActionCall(d,function(d){c(d.data);b.setValue(a.data("selected-id"),!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){d.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize,c=b.getValue();b.clearOptions();b.load(function(d){var f=sysPassApp.requests.getRequestOpts();
-f.url=e.entrypoint;f.method="get";f.data={r:a.data("item-route"),sk:sysPassApp.sk.get()};sysPassApp.requests.getActionCall(f,function(a){d(a);b.setValue(c,!0)})})}},ldap:{check:function(a){d.info("ldap:check");var b=$(a.data("src")),c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&
-h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){d.info("ldap:import");var b=''+sysPassApp.config.LANG[57]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],
-onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},track:{unlock:function(a){d.info("track:unlock");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,
-function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){d.info("track:clear");var b=''+sysPassApp.config.LANG[71]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}}}};
+sysPassApp.config.LANG[20]+"";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}},ajaxUrl:e,plugin:{toggle:function(a){d.info("plugin:enable");g.state.update(a);var b=a.data("item-id"),c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.method="get";c.data={r:a.data("action-route")+
+"/"+b,sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){d.info("plugin:reset");var b=''+sysPassApp.config.LANG[58]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],
+onClick:function(b){b.preventDefault();g.save(a)}}})},search:function(a){d.info("plugin:search");m.search(a)},show:function(a){d.info("plugin:show");t.show(a)},save:function(a){d.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){d.info("plugin:nav");m.nav(a)}},notification:{check:function(a){d.info("notification:check");
+var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")});sysPassApp.sk.set(b.csrf)})},search:function(a){d.info("notification:search");m.search(a)},show:function(a){d.info("notification:show");t.show(a)},save:function(a){d.info("notification:save");var b=sysPassApp.requests.getRequestOpts();
+b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},delete:function(a){d.info("notification:delete");m.delete(a,function(b){var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.method="get";c.data={r:a.data("action-route")+(0===b.length?"/"+a.data("item-id"):""),items:b,sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(c,
+function(b){sysPassApp.msg.out(b);f({r:a.data("action-next")})})})},getActive:function(){d.info("notification:getActive");var a=sysPassApp.requests.getRequestOpts();a.url=e.entrypoint;a.method="get";a.data={r:"items/notifications",sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(a,function(a){return a})},nav:function(a){d.info("eventlog:nav");m.nav(a)}},wiki:{show:function(a){d.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data=
+{pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,function(a){0!==a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){d.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(c){var d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint;d.method="get";d.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};sysPassApp.requests.getActionCall(d,function(d){c(d.data);b.setValue(a.data("selected-id"),
+!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){d.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize,c=b.getValue();b.clearOptions();b.load(function(d){var f=sysPassApp.requests.getRequestOpts();f.url=e.entrypoint;f.method="get";f.data={r:a.data("item-route"),sk:sysPassApp.sk.get()};sysPassApp.requests.getActionCall(f,function(a){d(a);b.setValue(c,!0)})})}},ldap:{check:function(a){d.info("ldap:check");var b=$(a.data("src")),c=sysPassApp.requests.getRequestOpts();c.url=
+e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){d.info("ldap:import");var b=''+sysPassApp.config.LANG[57]+
+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},track:{unlock:function(a){d.info("track:unlock");
+var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:sysPassApp.sk.get(),isAjax:1};sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){d.info("track:clear");var b=''+sysPassApp.config.LANG[71]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},
+positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}}}};
diff --git a/public/js/app-main.js b/public/js/app-main.js
index f15e6a42..440d920c 100644
--- a/public/js/app-main.js
+++ b/public/js/app-main.js
@@ -31,8 +31,8 @@ sysPass.Main = function () {
log.info("checkPluginUpdates");
for (const plugin in oPublic.plugins) {
- if (typeof oPublic.plugins.plugin.checkVersion === "function") {
- oPublic.plugins.plugin.checkVersion().then(function (json) {
+ if (typeof oPublic.plugins[plugin].checkVersion === "function") {
+ oPublic.plugins[plugin].checkVersion().then(function (json) {
if (json.status === 0 && json.data.plugin !== undefined) {
msg.info(String.format(oPublic.config.LANG[67], json.data.plugin, json.data.remoteVersion));
}
@@ -52,11 +52,13 @@ sysPass.Main = function () {
for (let i = 0; i < oPublic.config.PLUGINS.length; i++) {
const plugin = oPublic.config.PLUGINS[i];
- if (typeof sysPass.Plugin[plugin] === "function") {
- plugins.plugin = sysPass.Plugin[plugin]();
+ if (typeof sysPass.Plugins[plugin] === "function") {
+ plugins[plugin] = sysPass.Plugins[plugin](oPublic);
}
}
+ log.info(plugins);
+
return plugins;
};
diff --git a/public/js/app-main.min.js b/public/js/app-main.min.js
index f32dce48..dd166eab 100644
--- a/public/js/app-main.min.js
+++ b/public/js/app-main.min.js
@@ -1,4 +1,4 @@
-sysPass.Main=function(){var k=function(){d.info("checkPluginUpdates");for(var a in b.plugins)"function"===typeof b.plugins.plugin.checkVersion&&b.plugins.plugin.checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&e.info(String.format(b.config.LANG[67],a.data.plugin,a.data.remoteVersion))})},l=function(){d.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);if(!a.hasClass("passwordfield__no-pki"))try{g(a)}catch(c){d.error(c),e.error(c)}}).on("keypress",
+sysPass.Main=function(){var k=function(){d.info("checkPluginUpdates");for(var a in b.plugins)"function"===typeof b.plugins[a].checkVersion&&b.plugins[a].checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&e.info(String.format(b.config.LANG[67],a.data.plugin,a.data.remoteVersion))})},l=function(){d.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);if(!a.hasClass("passwordfield__no-pki"))try{g(a)}catch(c){d.error(c),e.error(c)}}).on("keypress",
":input[type=password]",function(a){if(13===a.keyCode){a.preventDefault();a=$(this);try{g(a)}catch(c){d.error(c),e.error(c)}a.closest("form").submit()}})},m=function(){d.info("initializeClipboard");if(clipboard.isSupported())$("body").on("click",".clip-pass-button",function(){var a=sysPassApp.actions.account.copyPass($(this)).done(function(a){if(0!==a.status)return e.out(a),!1;h.set(a.csrf)});!1!==a&&clipboard.copy(a.responseJSON.data.accpass).then(function(){e.ok(b.config.LANG[45])},function(a){e.error(b.config.LANG[46])})}).on("click",
".dialog-clip-button",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(a.text().replace(/\r?\n|\r/g)).then(function(){$(".dialog-text").removeClass("dialog-clip-copy");a.addClass("dialog-clip-copy")},function(a){e.error(b.config.LANG[46])})}).on("click",".clip-pass-icon",function(){clipboard.copy(sysPass.Util.decodeEntities($(this.dataset.clipboardTarget).val())).then(function(){e.ok(b.config.LANG[45])},function(a){e.error(b.config.LANG[46])})}).on("click",".clip-pass-field",function(){clipboard.copy(sysPass.Util.decodeEntities(document.getElementById(this.dataset.clipboardTarget).dataset.pass)).then(function(){e.ok(b.config.LANG[45])},
function(a){e.error(b.config.LANG[46])})});else d.warn(b.config.LANG[65])},g=function(a){d.info("encryptFormValue");var c=a.val();if(""!==c&&parseInt(a.attr("data-length"))!==c.length){if(c.length>b.config.PKI.MAX_SIZE)throw a.val(""),"Data length too big for encrypting";c=b.config.PKI.CRYPTO.encrypt(c);a.val(c);a.attr("data-length",c.length)}},p=function(){d.info("checkLogout");return"login/logout"===n("r")?(e.sticky(b.config.LANG[61],function(){b.util.redirect("index.php?r=login")}),!0):!1},h={current:"",
@@ -9,4 +9,4 @@ case 100:this.ok(b);this.sticky(b);break;case 101:this.error(b);this.sticky(b);b
c=sysPass.Config();c.setAppRoot(window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}());var f=b.requests.getRequestOpts();f.url="/index.php?r=bootstrap/getEnvironment";f.method="get";f.useLoading=!1;f.data={isAjax:1};return b.requests.getActionCall(f,function(a){void 0!==a.data&&(c.setLang(a.data.lang),c.setPkiKey(a.data.pki_key),c.setPkiSize(a.data.pki_max_size),c.setCheckUpdates(a.data.check_updates),c.setCheckNotices(a.data.check_notices),
c.setTimezone(a.data.timezone),c.setLocale(a.data.locale),c.setDebugEnabled(a.data.debug),c.setFileMaxSize(a.data.max_file_size),c.setFileAccountAllowedExts(a.data.files_allowed_exts),c.setFileImportAllowedExts(a.data.import_allowed_exts),c.setCookiesEnabled(a.data.cookies_enabled),c.setPlugins(a.data.plugins),c.setLoggedIn(a.data.loggedin),c.setAuthBasicAutologinEnabled(a.data.authbasic_autologin),c.initialize(),b.config=c.getConfig())}).fail(function(){e.error("Error while getting sysPass config
Please try again or check web server logs")})},
b={config:sysPass.Config().getConfig(),actions:sysPass.Actions(d),triggers:sysPass.Triggers(d),util:sysPass.Util(d),theme:{},plugins:{},sk:h,msg:e,log:d,encryptFormValue:g},n=function(a){for(var b=[],d,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),g=0;gform").each(function(){var a=$(this);a.find("button.btn-clear").on("click",function(b){b.preventDefault();a.trigger("reset")})})},config:function(){c.info("views:config");var a=$("#drop-import-files");if(0form").each(function(){var a=$(this);a.find("button.btn-clear").on("click",function(b){b.preventDefault();a.trigger("reset")})})},config:function(){c.info("views:config");var a=$("#drop-import-files");if(01
1
- aaeac4305c3720ad2583da0b48fe9e8772baf830
+ 469d8c9e4929938ef00640f07de42d56e3b9b29b
0
0
- 1539293913
- f53ab0a1ef713674d6398b4e188e098b4090166c
+ 1539562721
+ 70ced48a5cd70bf112f386361d4c10ac603132fe
@@ -32,7 +32,7 @@
0
- 6f2ae342398f2315be1702fa560634b8f1a3e408
+ 0dcdb304c5e122e25fbbb97f5b9de17f87195c62
- PDF
- JPG