Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion data/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2600,7 +2600,7 @@ last_login {
plugin: 'last-login',
values: setting_types.STRING,
text: `
The key that is updated in the dictionary with the last login information.`
The key that is updated in the dictionary with the last login timestamp.`
},

last_login_precision: {
Expand All @@ -2611,6 +2611,18 @@ The key that is updated in the dictionary with the last login information.`
text: `Precision for last login timestamp.`
},

last_login_dict_fields: {
default: '',
added: {
settings_last_login_dict_fields_added: false
},
plugin: 'last-login',
values: setting_types.STRING,
text: `
Space-separated list of additional \`key=value\` pairs to be updated in the
dictionary. Both keys and values support variable expansion.`
},

/* lazy-expunge plugin */

lazy_expunge_mailbox: {
Expand Down
1 change: 1 addition & 0 deletions data/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export const updates = {
settings_imapc_ssl_verify_removed: '2.4.0',
settings_inet_listener_type_added: '2.4.0',
settings_lazy_expunge_only_last_instance_changed: '2.4.3',
settings_last_login_dict_fields_added: '2.4.X',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2.4.5 likely.

settings_login_socket_path_added: '2.4.0',
settings_lmtp_user_concurrency_limit_changed: '2.4.1',
settings_mail_access_groups_changed: '2.4.3',
Expand Down
42 changes: 33 additions & 9 deletions docs/core/plugins/last_login.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ to include `%{service}`.

### MySQL Example

This includes the service and remote IP address as well.
This includes the service and remote IP address as well. Using
`last_login_dict_fields` ensures that both the timestamp and the IP address are
updated if a login record for that user/service already exists.

::: code-group

Expand All @@ -69,7 +71,8 @@ last_login {
dict proxy {
name = sql
}
key = last-login/%{service}/%{user}/%{remote_ip}
key = last-login/%{service}/%{user}/access
last_login_dict_fields = last-login/%{service}/%{user}/ip=%{remote_ip}
precision = ms
}

Expand All @@ -82,7 +85,7 @@ dict_server {
password = pass
}

dict_map shared/last-login/$service/$user/$remote_ip {
dict_map shared/last-login/$service/$user/access {
sql_table = last_login
value_field last_access {
type = uint
Expand All @@ -94,8 +97,18 @@ dict_server {
key_field service {
value = $service
}
key_field last_ip {
value = $remote_ip
}

dict_map shared/last-login/$service/$user/ip {
sql_table = last_login
value_field last_ip {
}

key_field userid {
value = $user
}
key_field service {
value = $service
}
}
}
Expand Down Expand Up @@ -125,7 +138,8 @@ last_login {
name = cassandra
socket_path = dict-async
}
key = last-login/%{service}/%{user}/%{remote_ip}
key = last-login/%{service}/%{user}/access
last_login_dict_fields = last-login/%{service}/%{user}/ip=%{remote_ip}
precision = ms
}

Expand All @@ -140,7 +154,7 @@ dict_server {
password = pass
}

dict_map shared/last-login/$service/$user/$remote_ip {
dict_map shared/last-login/$service/$user/access {
sql_table = last_login
value_field last_access {
type = uint
Expand All @@ -152,8 +166,18 @@ dict_server {
key_field service {
value = $service
}
key_field last_ip {
value = $remote_ip
}

dict_map shared/last-login/$service/$user/ip {
sql_table = last_login
value_field last_ip {
}

key_field userid {
value = $user
}
key_field service {
value = $service
}
}
}
Expand Down
Loading