connlog.html 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Connection Log</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
  7. <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
  8. <script type="text/javascript" src="../../script/jquery.min.js"></script>
  9. <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
  10. <style>
  11. </style>
  12. </head>
  13. <body>
  14. <div class="ui container" style="height: 100% !important;">
  15. <div>
  16. <p>Connection Attempts</p>
  17. <h1 class="ui header">
  18. <span id="normalStatus">Analysising</span>
  19. <div class="sub header">
  20. <span id="loginAptCount"></span> login request logged this month with <span id="incorrectRatio"></span> incorrect password attempts.
  21. </div>
  22. </h1>
  23. <div class="ui divider"></div>
  24. <div class="ui fluid selection dropdown">
  25. <input type="hidden" name="tablekey" onchange="loadRecords(this);">
  26. <i class="dropdown icon"></i>
  27. <div class="default text">Date</div>
  28. <div id="recordTables" class="menu">
  29. </div>
  30. </div>
  31. </div>
  32. <div class="ui divider"></div>
  33. <div>
  34. <table class="ui celled table">
  35. <thead>
  36. <tr>
  37. <th>Accepted</th>
  38. <th>Timestamp</th>
  39. <th>Requested Account</th>
  40. <th>IP Address</th>
  41. <th>Connection Type</th>
  42. <th>Access Port</th>
  43. </tr>
  44. </thead>
  45. <tbody id="records">
  46. </tbody>
  47. </table>
  48. </div>
  49. <br><br>
  50. </div>
  51. <script>
  52. var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  53. $(".ui.dropdown").dropdown();
  54. initMonthList();
  55. //Get the table that belongs to today. Put in offset if the current month not found in list
  56. function getCurrentMonthTable(monOffset = 0){
  57. const d = new Date();
  58. return monthNames[d.getMonth() - monOffset] + "-" + d.getFullYear()
  59. }
  60. //Get the month list
  61. function initMonthList(){
  62. $.ajax({
  63. url: "../../system/auth/logger/index",
  64. success: function(data){
  65. var currentMonthTable = getCurrentMonthTable();
  66. var currentMontHTableExists = false;
  67. if (data.error){
  68. alert(data.error);
  69. }else{
  70. $("#recordTables").html("");
  71. data.forEach(tableName => {
  72. if (tableName == currentMonthTable){
  73. currentMontHTableExists = true;
  74. }
  75. $("#recordTables").append(`<div class="item" data-value="${tableName}">${tableName}</div>`);
  76. });
  77. if (data.length == 0){
  78. //No record
  79. $("#normalStatus").parent().attr("class","ui header");
  80. $("#normalStatus").text("No Record");
  81. $("#incorrectRatio").text("0%");
  82. $("#loginAptCount").text("0");
  83. }
  84. }
  85. //Select the current month if it exists
  86. if (currentMontHTableExists){
  87. setTimeout(function(){
  88. $("#recordTables").parent().dropdown("set selected", getCurrentMonthTable());
  89. }, 500);
  90. loadRecordsByTableName(getCurrentMonthTable());
  91. }
  92. }
  93. });
  94. }
  95. function loadRecordsByTableName(tableName){
  96. $.ajax({
  97. url: "../../system/auth/logger/list",
  98. data: {record: tableName},
  99. success: function(data){
  100. $("#records").html("");
  101. if (data.error !== undefined){
  102. $("#records").html(`<tr>
  103. <td data-label="status" colspan="5"><i class="remove icon"></i> ${data.error}</td>
  104. </tr>`);
  105. }else{
  106. if (data.length == 0){
  107. $("#records").html(`<tr>
  108. <td data-label="status" colspan="5"><i class="checkmark icon"></i> No login record in this time period.</td>
  109. </tr>`);
  110. }else{
  111. //console.log(data);
  112. //Reverse the array so the latest login on top
  113. data.reverse();
  114. data.forEach(entry => {
  115. var timestamp = getDatetimeFromTimestamp(entry.Timestamp);
  116. var statusIcon = `<i class="green checkmark icon"></i>`;
  117. if (entry.LoginSucceed == false){
  118. statusIcon = `<i class="red remove icon"></i>`;
  119. }
  120. var authType = entry.AuthType;
  121. if (authType == ""){
  122. authType = "N/A"
  123. }else if (authType == "web"){
  124. authType = `<i class="blue globe icon"></i> Web Interface`
  125. }else if (authType == "ftp"){
  126. authType = `<i class="yellow folder icon"></i> FTP`
  127. }else if (authType == "webdav"){
  128. authType = `<i class="blue folder icon"></i> WebDAV`
  129. }
  130. $("#records").append(`<tr>
  131. <td data-label="status">${statusIcon}</td>
  132. <td data-label="timestamp">${timestamp}</td>
  133. <td data-label="acc">${entry.TargetUsername}</td>
  134. <td data-label="ip">${entry.IpAddr}</td>
  135. <td data-label="authtype">${authType}</td>
  136. <td data-label="port">${entry.Port}</td>
  137. </tr>`);
  138. });
  139. updateSummaryText(data);
  140. }
  141. }
  142. }
  143. });
  144. }
  145. function loadRecords(object){
  146. var tableName = object.value;
  147. loadRecordsByTableName(tableName);
  148. }
  149. function updateSummaryText(records){
  150. if (records.length == 0){
  151. $("#normalStatus").parent().attr("class","ui header");
  152. $("#normalStatus").text("No Record");
  153. $("#loginAptCount").text("No ");
  154. return;
  155. }
  156. var succ = 0;
  157. var failed = 0;
  158. //Calculate the risk ratio
  159. records.forEach(entry => {
  160. if (entry.LoginSucceed){
  161. succ++;
  162. }else{
  163. failed++;
  164. }
  165. });
  166. //Do a quick summary
  167. var failRatio = (failed) / (succ + failed) * 100;
  168. if (failRatio > 70){
  169. $("#normalStatus").parent().attr("class","ui red header");
  170. $("#normalStatus").text("HIGH RISK");
  171. }else if (failRatio > 50){
  172. $("#normalStatus").parent().attr("class","ui yellow header");
  173. $("#normalStatus").text("LOW RISK");
  174. }else{
  175. // No problem
  176. $("#normalStatus").parent().attr("class","ui green header");
  177. $("#normalStatus").text("Normal");
  178. }
  179. $("#incorrectRatio").text(failRatio.toFixed(1) + "%");
  180. $("#loginAptCount").text(succ + failed);
  181. }
  182. function getDatetimeFromTimestamp(timestamp){
  183. var s = new Date(timestamp * 1000);
  184. var localOption =Intl.DateTimeFormat().resolvedOptions()
  185. var options = { timeZone: 'UTC' };
  186. if (localOption != undefined && localOption.timeZone != undefined){
  187. options.timeZone = localOption.timeZone;
  188. }
  189. return s.toLocaleDateString(undefined,options) + " " + s.toLocaleTimeString(undefined,options);
  190. }
  191. </script>
  192. </body>
  193. </html>