Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordizzy <diosmosis@users.noreply.github.com>2022-08-17 16:02:28 +0300
committerGitHub <noreply@github.com>2022-08-17 16:02:28 +0300
commit8877d15cc94ff4240cb72b836e4eb07824b871e5 (patch)
tree294a93b6600cb3332c34700a63fb2529b12e3099 /plugins/Login
parent585da9e91a7528d12b8fac9f3d58911b4eb1a15e (diff)
[Vue] remove angularjs from Login plugin (#19417)
* convert twig templates using directives to vue components, remove angularjs adapters and modify less styles that use directive attribute names * built vue files * move use of angularjs directives in TwoFactorAuth twig templates to new vue components and add vue component for Logins formErrors.twig template * built vue files * remove use of angularjs from Login plugin * built vue files * add missing translations * fixing UI tests * more UI test fixex * remove reference to nonexistant JS file * updated expected screenshots * fixing ui test failures * update expected screenshots * fixing ui test failures * fix select on focus use * fix placement of computed property * fixing ui test issues * prevent random failure * make sure Login plugin UMD is always loaded * formErrors is an object if supplied * compile vue entry components in reset API response and modify check for success * rebuild login * update expected screenshot * remove unneeded use of html_attr escape * remove use of unneeded twig escape filter, html_attr + remove duplicate translations * fix brute force log Co-authored-by: sgiehl <stefan@matomo.org>
Diffstat (limited to 'plugins/Login')
-rw-r--r--plugins/Login/Controller.php2
-rw-r--r--plugins/Login/Login.php10
-rw-r--r--plugins/Login/javascripts/bruteforcelog.js3
-rw-r--r--plugins/Login/templates/bruteForceLog.twig39
-rw-r--r--plugins/Login/templates/confirmPassword.twig2
-rw-r--r--plugins/Login/templates/confirmResetPassword.twig2
-rw-r--r--plugins/Login/templates/invitation.twig2
-rw-r--r--plugins/Login/templates/login.twig2
-rw-r--r--plugins/Login/vue/dist/Login.umd.js109
-rw-r--r--plugins/Login/vue/dist/Login.umd.min.js2
-rw-r--r--plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue84
-rw-r--r--plugins/Login/vue/src/index.ts1
12 files changed, 217 insertions, 41 deletions
diff --git a/plugins/Login/Controller.php b/plugins/Login/Controller.php
index c952368409..e8be13d477 100644
--- a/plugins/Login/Controller.php
+++ b/plugins/Login/Controller.php
@@ -282,7 +282,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
return $this->renderTemplate('bruteForceLog', [
'blockedIps' => $this->bruteForceDetection->getCurrentlyBlockedIps(),
- 'blacklistedIps' => $this->systemSettings->blacklistedBruteForceIps->getValue()
+ 'disallowedIps' => $this->systemSettings->blacklistedBruteForceIps->getValue()
]);
}
diff --git a/plugins/Login/Login.php b/plugins/Login/Login.php
index 350a80c0fe..2bf97938ff 100644
--- a/plugins/Login/Login.php
+++ b/plugins/Login/Login.php
@@ -36,6 +36,7 @@ class Login extends \Piwik\Plugin
public function registerEvents()
{
$hooks = array(
+ 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
'User.isNotAuthorized' => 'noAccess',
'API.Request.authenticate' => 'ApiRequestAuthenticate',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
@@ -80,6 +81,15 @@ class Login extends \Piwik\Plugin
return $hooks;
}
+ public function getClientSideTranslationKeys(&$translations)
+ {
+ $translations[] = 'Login_CurrentlyBlockedIPs';
+ $translations[] = 'Login_CurrentlyBlockedIPsUnblockInfo';
+ $translations[] = 'Login_UnblockAllIPs';
+ $translations[] = 'Login_CurrentlyBlockedIPsUnblockConfirm';
+ $translations[] = 'Login_IPsAlwaysBlocked';
+ }
+
public function isTrackerPlugin()
{
return true;
diff --git a/plugins/Login/javascripts/bruteforcelog.js b/plugins/Login/javascripts/bruteforcelog.js
index 443f9efc8f..da0034a896 100644
--- a/plugins/Login/javascripts/bruteforcelog.js
+++ b/plugins/Login/javascripts/bruteforcelog.js
@@ -13,10 +13,11 @@
ajaxRequest.addParams({
module: 'API',
method: 'Login.unblockBruteForceIPs',
+ format: 'json'
}, 'get');
ajaxRequest.setCallback(
function (response) {
- piwikHelper.reload();
+ piwikHelper.refreshAfter(0);
}
);
ajaxRequest.send();
diff --git a/plugins/Login/templates/bruteForceLog.twig b/plugins/Login/templates/bruteForceLog.twig
index da856790bf..6a384dbcb1 100644
--- a/plugins/Login/templates/bruteForceLog.twig
+++ b/plugins/Login/templates/bruteForceLog.twig
@@ -4,39 +4,10 @@
{% block content %}
- <div piwik-content-block content-title="{{ 'Login_CurrentlyBlockedIPs'|translate|e('html_attr') }}">
- {% if blockedIps is empty %}
- <p>{{ 'UserCountryMap_None'|translate }}</p>
- {% else %}
- <ul style="margin-left: 20px;">
- {% for blockedIp in blockedIps %}
- <li style="list-style: disc;">{{ blockedIp }}</li>
- {% endfor %}
- </ul>
- {% endif %}
-
- {% if blockedIps is not empty %}
- <p><br />{{ 'Login_CurrentlyBlockedIPsUnblockInfo'|translate }}</p>
-
- <div>
- <input type="button" class="btn" value="{{ 'Login_UnblockAllIPs'|translate }}" onclick="bruteForceLog.unblockAllIps();">
- </div>
-
- <div id="confirmUnblockAllIps" class="ui-confirm">
- <h2>{{ 'Login_CurrentlyBlockedIPsUnblockConfirm'|translate }}</h2>
- <input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
- <input role="no" type="button" value="{{ 'General_No'|translate }}"/>
- </div>
- {% endif %}
-
- {% if blacklistedIps is not empty %}
- <h3>{{ 'Login_IPsAlwaysBlocked'|translate }}</h3>
- <ul style="margin-left: 20px;">
- {% for blacklistedIp in blacklistedIps %}
- <li style="list-style: disc;">{{ blacklistedIp }}</li>
- {% endfor %}
- </ul>
- {% endif %}
- </div>
+ <div
+ vue-entry="Login.BruteForceLog"
+ blocked-ips="{{ blockedIps|json_encode }}"
+ disallowed-ips="{{ disallowedIps|json_encode }}"
+ ></div>
{% endblock %}
diff --git a/plugins/Login/templates/confirmPassword.twig b/plugins/Login/templates/confirmPassword.twig
index 2346a888a9..0ea3abc525 100644
--- a/plugins/Login/templates/confirmPassword.twig
+++ b/plugins/Login/templates/confirmPassword.twig
@@ -10,7 +10,7 @@
{{ postEvent("Template.confirmPasswordContent", "top") }}
<div class="message_container">
{% if AccessErrorString %}
- <div piwik-notification
+ <div vue-entry="CoreHome.Notification"
noclear="true"
context="error">
<strong>{{ 'General_Error'|translate }}</strong>: {{ AccessErrorString|raw }}<br/>
diff --git a/plugins/Login/templates/confirmResetPassword.twig b/plugins/Login/templates/confirmResetPassword.twig
index 4abb1b82dd..80ef8043a5 100644
--- a/plugins/Login/templates/confirmResetPassword.twig
+++ b/plugins/Login/templates/confirmResetPassword.twig
@@ -10,7 +10,7 @@
<div class="message_container">
{% if errorMessage is not empty %}
- <div piwik-notification
+ <div vue-entry="CoreHome.Notification"
noclear="true"
context="error">
<strong>{{ 'General_Error'|translate }}</strong>: {{ errorMessage }}<br/>
diff --git a/plugins/Login/templates/invitation.twig b/plugins/Login/templates/invitation.twig
index a559a9aab4..fbb45e427f 100644
--- a/plugins/Login/templates/invitation.twig
+++ b/plugins/Login/templates/invitation.twig
@@ -9,7 +9,7 @@
</div>
{% if AccessErrorString is defined %}
- <div piwik-notification
+ <div vue-entry="CoreHome.Notification"
noclear="true"
context="error">
<strong>{{ 'General_Error'|translate }}</strong>: {{ AccessErrorString|raw }}<br/>
diff --git a/plugins/Login/templates/login.twig b/plugins/Login/templates/login.twig
index e2e9ecf6f0..17ac9f776d 100644
--- a/plugins/Login/templates/login.twig
+++ b/plugins/Login/templates/login.twig
@@ -10,7 +10,7 @@
{{ include('@Login/_formErrors.twig', {formErrors: form_data.errors } ) }}
{% if AccessErrorString %}
- <div piwik-notification
+ <div vue-entry="CoreHome.Notification"
noclear="true"
context="error">
<strong>{{ 'General_Error'|translate }}</strong>: {{ AccessErrorString|raw }}<br/>
diff --git a/plugins/Login/vue/dist/Login.umd.js b/plugins/Login/vue/dist/Login.umd.js
index cbf4f257d3..c65fce898f 100644
--- a/plugins/Login/vue/dist/Login.umd.js
+++ b/plugins/Login/vue/dist/Login.umd.js
@@ -119,6 +119,7 @@ __webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, "FormErrors", function() { return /* reexport */ FormErrors; });
+__webpack_require__.d(__webpack_exports__, "BruteForceLog", function() { return /* reexport */ BruteForceLog; });
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
// This file is imported into lib/wc client bundles.
@@ -193,6 +194,113 @@ var external_CoreHome_ = __webpack_require__("19dc");
FormErrorsvue_type_script_lang_ts.render = render
/* harmony default export */ var FormErrors = (FormErrorsvue_type_script_lang_ts);
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue?vue&type=template&id=4e87a650
+
+var BruteForceLogvue_type_template_id_4e87a650_hoisted_1 = {
+ key: 0
+};
+var BruteForceLogvue_type_template_id_4e87a650_hoisted_2 = {
+ key: 1,
+ style: {
+ "margin-left": "20px"
+ }
+};
+var BruteForceLogvue_type_template_id_4e87a650_hoisted_3 = {
+ key: 2
+};
+
+var _hoisted_4 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1);
+
+var _hoisted_5 = ["value"];
+var _hoisted_6 = {
+ id: "confirmUnblockAllIps",
+ class: "ui-confirm"
+};
+var _hoisted_7 = ["value"];
+var _hoisted_8 = ["value"];
+var _hoisted_9 = {
+ key: 3
+};
+var _hoisted_10 = {
+ style: {
+ "margin-left": "20px"
+ }
+};
+function BruteForceLogvue_type_template_id_4e87a650_render(_ctx, _cache, $props, $setup, $data, $options) {
+ var _component_ContentBlock = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("ContentBlock");
+
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createBlock"])(_component_ContentBlock, {
+ "content-title": _ctx.translate('Login_CurrentlyBlockedIPs')
+ }, {
+ default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () {
+ return [!_ctx.blockedIps.length ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("p", BruteForceLogvue_type_template_id_4e87a650_hoisted_1, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('UserCountryMap_None')), 1)) : (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("ul", BruteForceLogvue_type_template_id_4e87a650_hoisted_2, [(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])(external_commonjs_vue_commonjs2_vue_root_Vue_["Fragment"], null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["renderList"])(_ctx.blockedIps, function (blockedIp, index) {
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("li", {
+ style: {
+ "list-style": "disc"
+ },
+ key: index
+ }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(blockedIp), 1);
+ }), 128))])), _ctx.blockedIps.length ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", BruteForceLogvue_type_template_id_4e87a650_hoisted_3, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", null, [_hoisted_4, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createTextVNode"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Login_CurrentlyBlockedIPsUnblockInfo')), 1)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ type: "button",
+ class: "btn",
+ value: _ctx.translate('Login_UnblockAllIPs'),
+ onClick: _cache[0] || (_cache[0] = function ($event) {
+ return _ctx.unblockAllIps();
+ })
+ }, null, 8, _hoisted_5)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_6, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Login_CurrentlyBlockedIPsUnblockConfirm')), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ role: "yes",
+ type: "button",
+ value: _ctx.translate('General_Yes')
+ }, null, 8, _hoisted_7), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ role: "no",
+ type: "button",
+ value: _ctx.translate('General_No')
+ }, null, 8, _hoisted_8)])])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), _ctx.disallowedIps.length ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_9, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h3", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Login_IPsAlwaysBlocked')), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("ul", _hoisted_10, [(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])(external_commonjs_vue_commonjs2_vue_root_Vue_["Fragment"], null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["renderList"])(_ctx.disallowedIps, function (ip, index) {
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("li", {
+ style: {
+ "list-style": "disc"
+ },
+ key: index
+ }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(ip), 1);
+ }), 128))])])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)];
+ }),
+ _: 1
+ }, 8, ["content-title"]);
+}
+// CONCATENATED MODULE: ./plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue?vue&type=template&id=4e87a650
+
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-2!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue?vue&type=script&lang=ts
+
+
+/* harmony default export */ var BruteForceLogvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({
+ props: {
+ blockedIps: {
+ type: Array,
+ required: true
+ },
+ disallowedIps: {
+ type: Array,
+ required: true
+ }
+ },
+ components: {
+ ContentBlock: external_CoreHome_["ContentBlock"]
+ },
+ methods: {
+ unblockAllIps: function unblockAllIps() {
+ window.bruteForceLog.unblockAllIps();
+ }
+ }
+}));
+// CONCATENATED MODULE: ./plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue?vue&type=script&lang=ts
+
+// CONCATENATED MODULE: ./plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue
+
+
+
+BruteForceLogvue_type_script_lang_ts.render = BruteForceLogvue_type_template_id_4e87a650_render
+
+/* harmony default export */ var BruteForceLog = (BruteForceLogvue_type_script_lang_ts);
// CONCATENATED MODULE: ./plugins/Login/vue/src/index.ts
/*!
* Matomo - free/libre analytics platform
@@ -201,6 +309,7 @@ FormErrorsvue_type_script_lang_ts.render = render
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
+
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib-no-default.js
diff --git a/plugins/Login/vue/dist/Login.umd.min.js b/plugins/Login/vue/dist/Login.umd.min.js
index 4a47fa8195..9a04d1b660 100644
--- a/plugins/Login/vue/dist/Login.umd.min.js
+++ b/plugins/Login/vue/dist/Login.umd.min.js
@@ -1,4 +1,4 @@
-(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t(require("CoreHome"),require("vue")):"function"===typeof define&&define.amd?define(["CoreHome"],t):"object"===typeof exports?exports["Login"]=t(require("CoreHome"),require("vue")):e["Login"]=t(e["CoreHome"],e["Vue"])})("undefined"!==typeof self?self:this,(function(e,t){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="plugins/Login/vue/dist/",r(r.s="fae3")}({"19dc":function(t,r){t.exports=e},"8bbf":function(e,r){e.exports=t},fae3:function(e,t,r){"use strict";if(r.r(t),r.d(t,"FormErrors",(function(){return p})),"undefined"!==typeof window){var n=window.document.currentScript,o=n&&n.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);o&&(r.p=o[1])}var c=r("8bbf"),i=Object(c["createTextVNode"])(": "),u=["innerHTML"],f=Object(c["createElementVNode"])("br",null,null,-1);function l(e,t,r,n,o,l){var a=Object(c["resolveComponent"])("Notification");return Object.keys(e.formErrors||{}).length?(Object(c["openBlock"])(),Object(c["createBlock"])(a,{key:0,noclear:!0,context:"error"},{default:Object(c["withCtx"])((function(){return[(Object(c["openBlock"])(!0),Object(c["createElementBlock"])(c["Fragment"],null,Object(c["renderList"])(e.formErrors,(function(t,r){return Object(c["openBlock"])(),Object(c["createElementBlock"])("span",{key:r},[Object(c["createElementVNode"])("strong",null,Object(c["toDisplayString"])(e.translate("General_Error")),1),i,Object(c["createElementVNode"])("span",{innerHTML:e.$sanitize(t)},null,8,u),f])})),128))]})),_:1})):Object(c["createCommentVNode"])("",!0)}var a=r("19dc"),d=Object(c["defineComponent"])({props:{formErrors:[Array,Object]},components:{Notification:a["Notification"]}});d.render=l;var p=d;
+(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t(require("CoreHome"),require("vue")):"function"===typeof define&&define.amd?define(["CoreHome"],t):"object"===typeof exports?exports["Login"]=t(require("CoreHome"),require("vue")):e["Login"]=t(e["CoreHome"],e["Vue"])})("undefined"!==typeof self?self:this,(function(e,t){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="plugins/Login/vue/dist/",n(n.s="fae3")}({"19dc":function(t,n){t.exports=e},"8bbf":function(e,n){e.exports=t},fae3:function(e,t,n){"use strict";if(n.r(t),n.d(t,"FormErrors",(function(){return d})),n.d(t,"BruteForceLog",(function(){return C})),"undefined"!==typeof window){var o=window.document.currentScript,r=o&&o.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);r&&(n.p=r[1])}var l=n("8bbf"),c=Object(l["createTextVNode"])(": "),i=["innerHTML"],u=Object(l["createElementVNode"])("br",null,null,-1);function a(e,t,n,o,r,a){var b=Object(l["resolveComponent"])("Notification");return Object.keys(e.formErrors||{}).length?(Object(l["openBlock"])(),Object(l["createBlock"])(b,{key:0,noclear:!0,context:"error"},{default:Object(l["withCtx"])((function(){return[(Object(l["openBlock"])(!0),Object(l["createElementBlock"])(l["Fragment"],null,Object(l["renderList"])(e.formErrors,(function(t,n){return Object(l["openBlock"])(),Object(l["createElementBlock"])("span",{key:n},[Object(l["createElementVNode"])("strong",null,Object(l["toDisplayString"])(e.translate("General_Error")),1),c,Object(l["createElementVNode"])("span",{innerHTML:e.$sanitize(t)},null,8,i),u])})),128))]})),_:1})):Object(l["createCommentVNode"])("",!0)}var b=n("19dc"),s=Object(l["defineComponent"])({props:{formErrors:[Array,Object]},components:{Notification:b["Notification"]}});s.render=a;var d=s,p={key:0},f={key:1,style:{"margin-left":"20px"}},j={key:2},O=Object(l["createElementVNode"])("br",null,null,-1),m=["value"],y={id:"confirmUnblockAllIps",class:"ui-confirm"},k=["value"],g=["value"],B={key:3},v={style:{"margin-left":"20px"}};function E(e,t,n,o,r,c){var i=Object(l["resolveComponent"])("ContentBlock");return Object(l["openBlock"])(),Object(l["createBlock"])(i,{"content-title":e.translate("Login_CurrentlyBlockedIPs")},{default:Object(l["withCtx"])((function(){return[e.blockedIps.length?(Object(l["openBlock"])(),Object(l["createElementBlock"])("ul",f,[(Object(l["openBlock"])(!0),Object(l["createElementBlock"])(l["Fragment"],null,Object(l["renderList"])(e.blockedIps,(function(e,t){return Object(l["openBlock"])(),Object(l["createElementBlock"])("li",{style:{"list-style":"disc"},key:t},Object(l["toDisplayString"])(e),1)})),128))])):(Object(l["openBlock"])(),Object(l["createElementBlock"])("p",p,Object(l["toDisplayString"])(e.translate("UserCountryMap_None")),1)),e.blockedIps.length?(Object(l["openBlock"])(),Object(l["createElementBlock"])("div",j,[Object(l["createElementVNode"])("p",null,[O,Object(l["createTextVNode"])(Object(l["toDisplayString"])(e.translate("Login_CurrentlyBlockedIPsUnblockInfo")),1)]),Object(l["createElementVNode"])("div",null,[Object(l["createElementVNode"])("input",{type:"button",class:"btn",value:e.translate("Login_UnblockAllIPs"),onClick:t[0]||(t[0]=function(t){return e.unblockAllIps()})},null,8,m)]),Object(l["createElementVNode"])("div",y,[Object(l["createElementVNode"])("h2",null,Object(l["toDisplayString"])(e.translate("Login_CurrentlyBlockedIPsUnblockConfirm")),1),Object(l["createElementVNode"])("input",{role:"yes",type:"button",value:e.translate("General_Yes")},null,8,k),Object(l["createElementVNode"])("input",{role:"no",type:"button",value:e.translate("General_No")},null,8,g)])])):Object(l["createCommentVNode"])("",!0),e.disallowedIps.length?(Object(l["openBlock"])(),Object(l["createElementBlock"])("div",B,[Object(l["createElementVNode"])("h3",null,Object(l["toDisplayString"])(e.translate("Login_IPsAlwaysBlocked")),1),Object(l["createElementVNode"])("ul",v,[(Object(l["openBlock"])(!0),Object(l["createElementBlock"])(l["Fragment"],null,Object(l["renderList"])(e.disallowedIps,(function(e,t){return Object(l["openBlock"])(),Object(l["createElementBlock"])("li",{style:{"list-style":"disc"},key:t},Object(l["toDisplayString"])(e),1)})),128))])])):Object(l["createCommentVNode"])("",!0)]})),_:1},8,["content-title"])}var N=Object(l["defineComponent"])({props:{blockedIps:{type:Array,required:!0},disallowedIps:{type:Array,required:!0}},components:{ContentBlock:b["ContentBlock"]},methods:{unblockAllIps:function(){window.bruteForceLog.unblockAllIps()}}});N.render=E;var C=N;
/*!
* Matomo - free/libre analytics platform
*
diff --git a/plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue b/plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue
new file mode 100644
index 0000000000..2d70ecb5ba
--- /dev/null
+++ b/plugins/Login/vue/src/BruteForceLog/BruteForceLog.vue
@@ -0,0 +1,84 @@
+<!--
+ Matomo - free/libre analytics platform
+ @link https://matomo.org
+ @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+-->
+
+<template>
+ <ContentBlock :content-title="translate('Login_CurrentlyBlockedIPs')">
+ <p v-if="!blockedIps.length">{{ translate('UserCountryMap_None') }}</p>
+ <ul style="margin-left: 20px;" v-else>
+ <li style="list-style: disc;" v-for="(blockedIp, index) in blockedIps" :key="index">
+ {{ blockedIp }}
+ </li>
+ </ul>
+
+ <div v-if="blockedIps.length">
+ <p>
+ <br />{{ translate('Login_CurrentlyBlockedIPsUnblockInfo') }}
+ </p>
+
+ <div>
+ <input
+ type="button"
+ class="btn"
+ :value="translate('Login_UnblockAllIPs')"
+ @click="unblockAllIps()"
+ />
+ </div>
+
+ <div id="confirmUnblockAllIps" class="ui-confirm">
+ <h2>{{ translate('Login_CurrentlyBlockedIPsUnblockConfirm') }}</h2>
+ <input role="yes" type="button" :value="translate('General_Yes')"/>
+ <input role="no" type="button" :value="translate('General_No')"/>
+ </div>
+ </div>
+
+ <div v-if="disallowedIps.length">
+ <h3>{{ translate('Login_IPsAlwaysBlocked') }}</h3>
+ <ul style="margin-left: 20px;">
+ <li
+ style="list-style: disc;"
+ v-for="(ip, index) in disallowedIps"
+ :key="index"
+ >
+ {{ ip }}
+ </li>
+ </ul>
+ </div>
+ </ContentBlock>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { ContentBlock } from 'CoreHome';
+
+declare global {
+ interface Window {
+ readonly bruteForceLog: {
+ unblockAllIps(): void;
+ };
+ }
+}
+
+export default defineComponent({
+ props: {
+ blockedIps: {
+ type: Array,
+ required: true,
+ },
+ disallowedIps: {
+ type: Array,
+ required: true,
+ },
+ },
+ components: {
+ ContentBlock,
+ },
+ methods: {
+ unblockAllIps() {
+ window.bruteForceLog.unblockAllIps();
+ },
+ },
+});
+</script>
diff --git a/plugins/Login/vue/src/index.ts b/plugins/Login/vue/src/index.ts
index 782dc0feeb..44e4bf18c8 100644
--- a/plugins/Login/vue/src/index.ts
+++ b/plugins/Login/vue/src/index.ts
@@ -6,3 +6,4 @@
*/
export { default as FormErrors } from './FormErrors/FormErrors.vue';
+export { default as BruteForceLog } from './BruteForceLog/BruteForceLog.vue';