diff options
author | moisseev <moiseev@mezonplus.ru> | 2023-05-26 16:12:23 +0300 |
---|---|---|
committer | moisseev <moiseev@mezonplus.ru> | 2023-05-26 16:12:23 +0300 |
commit | aed812a7388be8fb9217e4c75a19d12f0e27c324 (patch) | |
tree | 20b6a46cac503aa10a9b54508b69fbcd50810ba5 /interface | |
parent | c3b5b6fe0a536bd3ec0809ca12ad96502906c126 (diff) | |
download | rspamd-aed812a7388be8fb9217e4c75a19d12f0e27c324.tar.gz rspamd-aed812a7388be8fb9217e4c75a19d12f0e27c324.zip |
[WebUI] Add ability to compute fuzzy hashes
from sample message source
Diffstat (limited to 'interface')
-rw-r--r-- | interface/index.html | 37 | ||||
-rw-r--r-- | interface/js/app/upload.js | 54 |
2 files changed, 79 insertions, 12 deletions
diff --git a/interface/index.html b/interface/index.html index 2fad32b2f..ca991a8d2 100644 --- a/interface/index.html +++ b/interface/index.html @@ -427,11 +427,18 @@ </form> </div> </div> - <div class="card-footer"> - <button type="submit" class="btn btn-primary" data-upload="scan"><i class="fas fa-search"></i> Scan message</button> - <div class="float-end"> - <button class="btn btn-secondary d-inline-block" id="scanOptionsToggle" data-bs-toggle="collapse" data-bs-target="#scanOptions"><i class="fas fa-bars"></i> Options</button> - <button class="btn btn-secondary ms-2" id="scanClean"><i class="fas fa-trash-alt"></i> Clean form</button> + <div class="card-footer d-md-flex justify-content-between py-1"> + <div class="input-group d-inline-flex w-auto my-1"> + <button type="submit" class="btn btn-primary" data-upload="scan"><i class="fas fa-search"></i> Scan message</button> + <button class="btn btn-secondary d-inline-block" id="scanOptionsToggle" data-bs-toggle="collapse" data-bs-target="#scanOptions"><i class="fas fa-bars"></i> Options</button> + </div> + <div class="input-group d-inline-flex w-auto my-1"> + <label for="fuzzy-flag" class="input-group-text">Flag</label> + <input id="fuzzy-flag" class="form-control" value="1" min="1" type="number"> + <button class="btn btn-warning" data-upload="compute-fuzzy"><i class="fas fa-hashtag"></i> Compute fuzzy hashes</button> + </div> + <div class="float-end my-1"> + <button class="btn btn-secondary" id="scanClean"><i class="fas fa-trash-alt"></i> Clean form</button> </div> </div> </div> @@ -480,6 +487,26 @@ </div> </div> + <div id="hash-card" class="card bg-light shadow my-3" style="display: none;"> + <div class="card-header text-secondary py-2"> + <span class="icon me-3"><i class="fas fa-hashtag"></i></span> + <span class="h6 fw-bolder my-2">Fuzzy hashes</span> + <button type="button" class="card-close-btn btn-close float-end" aria-label="Close"></button> + </div> + <div class="card-body p-0 table-responsive"> + <table class="table status-table table-sm table-bordered text-nowrap mb-0" id="hashTable"> + <thead class="text-secondary"> + <tr> + <th>Rule name</th> + <th>Hashes</th> + </tr> + </thead> + <tbody> + </tbody> + </table> + </div> + </div> + <div class="card bg-light shadow my-3"> <div class="card-header text-secondary py-1 d-flex"> <span class="icon me-3"><i class="fas fa-eye"></i></span> diff --git a/interface/js/app/upload.js b/interface/js/app/upload.js index f9f6c53c6..1145db785 100644 --- a/interface/js/app/upload.js +++ b/interface/js/app/upload.js @@ -139,8 +139,13 @@ define(["jquery"], }]; } + function get_server(rspamd) { + var checked_server = rspamd.getSelector("selSrv"); + return (checked_server === "All SERVERS") ? "local" : checked_server; + } + // @upload text - function scanText(rspamd, tables, data, server, headers) { + function scanText(rspamd, tables, data, headers) { rspamd.query("checkv2", { data: data, params: { @@ -195,7 +200,39 @@ define(["jquery"], rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data"); } }, - server: server + server: get_server(rspamd) + }); + } + + function getFuzzyHashes(rspamd, data) { + function fillHashTable(rules) { + $("#hashTable tbody").empty(); + for (const [rule, hashes] of Object.entries(rules)) { + hashes.forEach(function (hash, i) { + $("#hashTable tbody").append("<tr>" + + (i === 0 ? '<td rowspan="' + Object.keys(hashes).length + '">' + rule + "</td>" : "") + + "<td>" + hash + "</td></tr>"); + }); + } + $("#hash-card").slideDown(); + } + + rspamd.query("plugins/fuzzy/hashes?flag=" + $("#fuzzy-flag").val(), { + data: data, + params: { + processData: false, + }, + method: "POST", + success: function (neighbours_status) { + var json = neighbours_status[0].data; + if (json.success) { + rspamd.alertMessage("alert-success", "Message successfully processed"); + fillHashTable(json.hashes); + } else { + rspamd.alertMessage("alert-error", "Unexpected error processing message"); + } + }, + server: get_server(rspamd) }); } @@ -230,22 +267,26 @@ define(["jquery"], $("html, body").animate({scrollTop:0}, 1000); return false; }); - // @init upload + + $(".card-close-btn").on("click", function () { + $(this).closest(".card").slideUp(); + }); + $("[data-upload]").on("click", function () { var source = $(this).data("upload"); var data = $("#scanMsgSource").val(); var headers = {}; if ($.trim(data).length > 0) { if (source === "scan") { - var checked_server = rspamd.getSelector("selSrv"); - var server = (checked_server === "All SERVERS") ? "local" : checked_server; headers = ["IP", "User", "From", "Rcpt", "Helo", "Hostname"].reduce(function (o, header) { var value = $("#scan-opt-" + header.toLowerCase()).val(); if (value !== "") o[header] = value; return o; }, {}); if ($("#scan-opt-pass-all").prop("checked")) headers.Pass = "all"; - scanText(rspamd, tables, data, server, headers); + scanText(rspamd, tables, data, headers); + } else if (source === "compute-fuzzy") { + getFuzzyHashes(rspamd, data); } else { if (source === "fuzzy") { headers = { @@ -262,6 +303,5 @@ define(["jquery"], }); }; - return ui; }); |