diff --git a/data/web/css/site/mailbox.css b/data/web/css/site/mailbox.css
index 81e1ff3f..2467ea33 100644
--- a/data/web/css/site/mailbox.css
+++ b/data/web/css/site/mailbox.css
@@ -57,8 +57,9 @@ table tbody tr td input[type="checkbox"] {
   font-size: 8pt !important;
 }
 .label-last-login {
-  line-height: 2.5;
+  line-height: 2.2;
   color: #4a4a4a!important;
+  padding: .2em .4em .3em !important;
   background-color: #ececec!important;
 }
 
diff --git a/data/web/css/site/user.css b/data/web/css/site/user.css
index 246453c1..bfbca47c 100644
--- a/data/web/css/site/user.css
+++ b/data/web/css/site/user.css
@@ -125,4 +125,8 @@ border-bottom-width: 3px;
 }
 .xmpp-logo-user {
   width:64px;
+}
+.recent-login-success {
+  margin-top:2px;
+  margin-right:10px;
 }
\ No newline at end of file
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index 0beea3b6..7854acd6 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -251,21 +251,21 @@ function password_check($password1, $password2) {
 
   return true;
 }
-function last_login($action, $username, $sasl_limit = 10) {
+function last_login($action, $username, $sasl_limit_days = 7) {
   global $pdo;
 	global $redis;
-  $sasl_limit = intval($sasl_limit);
+  $sasl_limit_days = intval($sasl_limit_days);
   switch ($action) {
     case 'get':
       if (filter_var($username, FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
         $stmt = $pdo->prepare('SELECT `real_rip`, MAX(`datetime`) as `datetime`, `service`, `app_password` FROM `sasl_logs`
           LEFT OUTER JOIN `app_passwd` on `sasl_logs`.`app_password` = `app_passwd`.`id`
           WHERE `username` = :username
+            AND HOUR(TIMEDIFF(NOW(), `datetime`)) < :sasl_limit_days
             AND `success` = 1
               GROUP BY `real_rip`, `service`, `app_password`
-              ORDER BY `datetime` DESC
-              LIMIT :sasl_limit;');
-        $stmt->execute(array(':username' => $username, ':sasl_limit' => $sasl_limit));
+              ORDER BY `datetime` DESC;');
+        $stmt->execute(array(':username' => $username, ':sasl_limit_days' => ($sasl_limit_days * 24)));
         $sasl = $stmt->fetchAll(PDO::FETCH_ASSOC);
         foreach ($sasl as $k => $v) {
           if (!filter_var($sasl[$k]['real_rip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php
index 7e9a24f3..5baa81d8 100644
--- a/data/web/inc/prerequisites.inc.php
+++ b/data/web/inc/prerequisites.inc.php
@@ -172,29 +172,12 @@ function exception_handler($e) {
 set_exception_handler('exception_handler');
 
 // TODO: Move function
-function get_remote_ip($anonymize = null) {
-  global $ANONYMIZE_IPS;
-  if ($anonymize === null) {
-    $anonymize = $ANONYMIZE_IPS;
-  }
-  elseif ($anonymize !== true && $anonymize !== false)  {
-    $anonymize = true;
-  }
+function get_remote_ip() {
   $remote = $_SERVER['REMOTE_ADDR'];
   if (filter_var($remote, FILTER_VALIDATE_IP) === false) {
     return '0.0.0.0';
   }
-  if ($anonymize) {
-    if (strlen(inet_pton($remote)) == 4) {
-      return inet_ntop(inet_pton($remote) & inet_pton("255.255.255.0"));
-    }
-    elseif (strlen(inet_pton($remote)) == 16) {
-      return inet_ntop(inet_pton($remote) & inet_pton('ffff:ffff:ffff:ffff:0000:0000:0000:0000'));
-    }
-  }
-  else {
-    return $remote;
-  }
+  return $remote;
 }
 
 // Load core functions first
diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php
index 1c3a2392..c390317f 100644
--- a/data/web/inc/vars.inc.php
+++ b/data/web/inc/vars.inc.php
@@ -82,24 +82,24 @@ $DEFAULT_LANG = 'en';
 // https://www.iso.org/obp/ui/#search
 // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
 $AVAILABLE_LANGUAGES = array(
-  'cs' => 'Čeština (Czech)',
-  'da' => 'Danish (Dansk)',
-  'de' => 'Deutsch (German)',
-  'en' => 'English',
-  'es' => 'Español (Spanish)',
-  'fi' => 'Suomi (Finish)',
-  'fr' => 'Français (French)',
-  'hu' => 'Magyar (Hungarian)',
-  'it' => 'Italiano (Italian)',
-  'ko' => '한국어 (Korean)',
-  'lv' => 'latviešu (Latvian)',
-  'nl' => 'Nederlands (Dutch)',
-  'pl' => 'Język Polski (Polish)',
-  'pt' => 'Português (Portuguese)',
-  'ro' => 'Română (Romanian)',
-  'ru' => 'Pусский (Russian)',
-  'sk' => 'Slovenčina (Slovak)',
-  'sv' => 'Svenska (Swedish)',
+  'cs' => 'Čeština (Czech)',
+  'da' => 'Danish (Dansk)',
+  'de' => 'Deutsch (German)',
+  'en' => 'English',
+  'es' => 'Español (Spanish)',
+  'fi' => 'Suomi (Finish)',
+  'fr' => 'Français (French)',
+  'hu' => 'Magyar (Hungarian)',
+  'it' => 'Italiano (Italian)',
+  'ko' => '한국어 (Korean)',
+  'lv' => 'latviešu (Latvian)',
+  'nl' => 'Nederlands (Dutch)',
+  'pl' => 'Język Polski (Polish)',
+  'pt' => 'Português (Portuguese)',
+  'ro' => 'Română (Romanian)',
+  'ru' => 'Pусский (Russian)',
+  'sk' => 'Slovenčina (Slovak)',
+  'sv' => 'Svenska (Swedish)',
   'zh' => '中文 (Chinese)'
 );
 
@@ -139,9 +139,6 @@ $OTP_LABEL = "mailcow UI";
 // How long to wait (in s) for cURL Docker requests
 $DOCKER_TIMEOUT = 60;
 
-// Anonymize IPs logged via UI
-$ANONYMIZE_IPS = true;
-
 // Split DKIM key notation (bind format)
 $SPLIT_DKIM_255 = false;
 
diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js
index d008b478..0a6d7ece 100644
--- a/data/web/js/site/mailbox.js
+++ b/data/web/js/site/mailbox.js
@@ -371,6 +371,7 @@ jQuery(function($){
             '<div class="label label-last-login">POP3 @ ' + unix_time_format(Number(res[1])) + '</div><br>' + 
             '<div class="label label-last-login">SMTP @ ' + unix_time_format(Number(res[2])) + '</div>';
         }},
+        {"name":"last_pw_change","filterable": false,"title":lang.last_pw_change,"breakpoints":"all"},
         {"name":"quarantine_notification","filterable": false,"title":lang.quarantine_notification,"breakpoints":"all"},
         {"name":"quarantine_category","filterable": false,"title":lang.quarantine_category,"breakpoints":"all"},
         {"name":"in_use","filterable": false,"type":"html","title":lang.in_use,"sortValue": function(value){
@@ -408,6 +409,12 @@ jQuery(function($){
             }
             */
             item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
+            if (item.attributes.passwd_update != '0') {
+              var last_pw_change = new Date(item.attributes.passwd_update.replace(/-/g, "/"));
+              item.last_pw_change = last_pw_change.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
+            } else {
+              item.last_pw_change = '-';
+            }
             item.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
             item.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
             item.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
diff --git a/data/web/js/site/user.js b/data/web/js/site/user.js
index 3b3956f1..88712d57 100644
--- a/data/web/js/site/user.js
+++ b/data/web/js/site/user.js
@@ -72,17 +72,15 @@ jQuery(function($){
   }
   acl_data = JSON.parse(acl);
 
-  $('.clear-last-logins').on('click', function () {
-    if (confirm(lang.delete_ays)) {
-      last_logins('reset');
-    }
-  })
+  $('.clear-last-logins').on('click', function () {if (confirm(lang.delete_ays)) {last_logins('reset');}})
+  $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).addClass('active').siblings().removeClass('active');});
 
-  function last_logins(action, lines = 10) {
+  function last_logins(action, days = 7) {
     if (action == 'get') {
+      $('.last-login').html('<i class="bi bi-hourglass"></i>' +  lang.waiting);
       $.ajax({
         dataType: 'json',
-        url: '/api/v1/get/last-login/' + encodeURIComponent(mailcow_cc_username) + '/' + lines,
+        url: '/api/v1/get/last-login/' + encodeURIComponent(mailcow_cc_username) + '/' + days,
         jsonp: false,
         error: function () {
           console.log('error reading last logins');
diff --git a/data/web/json_api.php b/data/web/json_api.php
index 3db775a4..ad4d9dbe 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -641,6 +641,7 @@ if (isset($_GET['query'])) {
 
           case "last-login":
             if ($object) {
+              // extra == days
               if (isset($extra) && intval($extra) >= 1) {
                 $data = last_login('get', $object, intval($extra));
               }
diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json
index a35ecf82..4f7f6065 100644
--- a/data/web/lang/lang.de.json
+++ b/data/web/lang/lang.de.json
@@ -736,6 +736,7 @@
         "insert_preset": "Beispiel \"%s\" laden",
         "kind": "Art",
         "last_mail_login": "Letzter Mail-Login",
+        "last_pw_change": "Letzte Passwortänderung",
         "last_run": "Letzte Ausführung",
         "last_run_reset": "Als nächstes ausführen",
         "mailbox": "Mailbox",
@@ -1052,7 +1053,9 @@
         "is_catch_all": "Ist Catch-All-Adresse für Domain(s)",
         "last_mail_login": "Letzter Mail-Login",
         "last_run": "Letzte Ausführung",
+        "last_pw_change": "Letzte Passwortänderung",
         "last_ui_login": "Letzte UI Anmeldung",
+        "login_history": "Login-Historie",
         "loading": "Lade...",
         "mailbox_details": "Mailbox-Details",
         "messages": "Nachrichten",
diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json
index fc015299..a3c6e429 100644
--- a/data/web/lang/lang.en.json
+++ b/data/web/lang/lang.en.json
@@ -734,6 +734,7 @@
         "insert_preset": "Insert example preset \"%s\"",
         "kind": "Kind",
         "last_mail_login": "Last mail login",
+        "last_pw_change": "Last password change",
         "last_run": "Last run",
         "last_run_reset": "Schedule next",
         "mailbox": "Mailbox",
@@ -1050,8 +1051,10 @@
         "is_catch_all": "Catch-all for domain/s",
         "last_mail_login": "Last mail login",
         "last_run": "Last run",
+        "last_pw_change": "Last password change",
         "last_ui_login": "Last UI login",
         "loading": "Loading...",
+        "login_history": "Login history",
         "mailbox_details": "Mailbox details",
         "messages": "messages",
         "month": "month",
diff --git a/data/web/user.php b/data/web/user.php
index bd7123d5..f9972fe0 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -174,9 +174,21 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
             <p><a target="_blank" href="https://mailcow.github.io/mailcow-dockerized-docs/client/#<?=$clientconfigstr;?>">[<?=$lang['user']['client_configuration'];?>]</a></p>
             <p><a href="#userFilterModal" data-toggle="modal">[<?=$lang['user']['show_sieve_filters'];?>]</a></p>
             <hr>
-            <h4><?=$lang['user']['recent_successful_connections'];?></h4>
-            <div class="last-login"><i class="bi bi-hourglass"></i> <?=$lang['user']['waiting'];?></div>
-            <span class="clear-last-logins"><?=$lang['user']['clear_recent_successful_connections'];?></span>
+            <h4 class="recent-login-success pull-left"><?=$lang['user']['recent_successful_connections'];?></h4>
+            <div class="dropdown pull-left">
+              <button class="btn btn-default btn-xs dropdown-toggle" type="button" id="history_sasl_days" data-toggle="dropdown"><?=$lang['user']['login_history'];?> <span class="caret"></span></button>
+              <ul class="dropdown-menu">
+                <li class="login-history" data-days="1"><a href="#">1 <?=$lang['user']['day'];?></a></li>
+                <li class="login-history" data-days="7"><a href="#">1 <?=$lang['user']['week'];?></a></li>
+                <li class="login-history active" data-days="14"><a href="#">2 <?=$lang['user']['weeks'];?></a></li>
+                <li class="login-history" data-days="31"><a href="#">1 <?=$lang['user']['month'];?></a></li>
+              </ul>
+            </div>
+            <div class="clearfix"></div>
+            <div class="last-login"></div>
+            <span class="clear-last-logins">
+              <?=$lang['user']['clear_recent_successful_connections'];?>
+            </span>
           </div>
         </div>
         <hr>