View Issue Details

IDProjectCategoryView StatusLast Update
3155Composrcorepublic2022-10-19 00:47
ReporterChris Graham Assigned ToPDStig  
PrioritynormalSeverityfeature 
Status resolvedResolutionfixed 
Summary3155: E-mails upon login/change password/change email address
DescriptionNotification option for when someone logs into your account, or changes your password or email address. i.e. any kind of account security event.
TagsHas Patch, Roadmap: v11, Type: Security
Attach Tags
Attached Files
sensitive-changed.diff (22,979 bytes)   
diff --git a/lang/EN/cns.ini b/lang/EN/cns.ini
index 77b9741..0ae8b30 100644
--- a/lang/EN/cns.ini
+++ b/lang/EN/cns.ini
@@ -528,8 +528,6 @@ PASSWORD_TOO_SHORT=The password must be at least {1} {1|character|characters}
 PASSWORD_TOO_LONG=The password must be at most {1} {1|character|characters}
 USERNAME_NUMERIC=Numeric usernames are not permitted
 USERNAME_PASSWORD_WHITESPACE=You must not use whitespace (e.g. spaces or tabs) in your username or password
-USERNAME_CHANGED_MAIL_SUBJECT=Your username has been changed
-USERNAME_CHANGED_MAIL=Your username on {1} has been changed to '{2}'.\nYou will need to use this username for future logins.
 STAFF_USERNAME_CHANGED_MAIL_SUBJECT={1} is now {2}
 STAFF_USERNAME_CHANGED_MAIL=The username on {1} has been changed to '{2}'.
 BAN_MEMBER=Ban member
@@ -690,9 +688,6 @@ DOC_DELETE_LURKERS=Lurkers are members that have registered but do not contribut
 SECRET_GROUP=(Secret usergroup #{1})
 HIDDEN_USERGROUP=Hidden usergroup
 DESCRIPTION_GROUP_HIDDEN=Whether the name and membership-list of this usergroup is hidden (from those who do not have the “See hidden usergroups and their membership” privilege). If you put members in this as a primary usergroup then the member's presence in a usergroup named “unknown” will be revealed along with the rank image.
-PASSWORD_CHANGED_MAIL_SUBJECT=Your password has been changed
-PASSWORD_CHANGED_MAIL_BODY=Your [b]{1}[/b] password has been changed.\n\nThis is a courtesy notice: no response is needed.\n\nIf you did not make this change and you have not requested it, you may wish to get in contact with the staff (in case your account has been hijacked).{2}
-PASSWORD_CHANGED_MAIL_BODY_2=\n\nThe Password Change request was made from:\nIP address: {1}
 RANK_IMAGE_PRI_ONLY=Rank image for primary members only
 RANK_IMAGE_PRI_ONLY_DESCRIPTION=Whether the rank image will only be shown for members who have this usergroup as their primary usergroup.
 FORUMS_AND_MEMBERS=Members, usergroups and forums
@@ -808,8 +803,6 @@ NOTIFICATION_TYPE_cns_new_pt=New Private Topic/Post with you
 NOTIFICATION_TYPE_cns_topic=Forum topic activity
 NOTIFICATION_TYPE_cns_group_join_request=Application to join your usergroup
 NOTIFICATION_TYPE_cns_group_declined=Your usergroup join request was declined
-NOTIFICATION_TYPE_cns_username_changed=Your username changed
-NOTIFICATION_TYPE_cns_password_changed=Your password changed
 NOTIFICATION_TYPE_cns_friend_birthday=Your friend's birthday is today
 NOTIFICATION_TYPE_cns_birthday=A member's birthday today
 NOTIFICATION_TYPE_cns_club=New club added
@@ -884,3 +877,13 @@ DESCRIPTION_ENABLE_AUTO_MARK_READ=Whether to mark topics as read automatically o
 AVATARS_CARTOONS=Cartoons
 AVATARS_THEMATIC=Hobbies
 AVATARS_MISC=Miscellaneous
+
+SECURITY_ASPECT_CHANGED_SUBJECT=Changes to sensitive areas of your account
+SECURITY_ASPECT_CHANGED_BODY=Hello {1},\n\nThis is an automatic courtesy e-mail to inform you that sensitive area(s) of your account on {3} have just been changed.\n\n{4}\n\nThe change(s) were made by {{{2}}}.\n\nIf you think these changes were not made legitimately, reply to this e-mail (just in case your account has been hijacked).{5}
+SECURITY_ASPECT_CHANGED_BODY_2=\n\nThe changes were made from:\nIP address: {1}
+SECURITY_ASPECT_CHANGED__USERNAME= - Your username from “{1}” to “{2}”.
+SECURITY_ASPECT_CHANGED__EMAIL_ADDRESS= - Your e-mail address from “{1}” to “{2}”.
+SECURITY_ASPECT_CHANGED__PASSWORD= - Your password.
+SECURITY_ASPECT_CHANGED__PHONE_NUMBER= - Your phone number from “{1}” to “{2}”.
+SENSITIVE_CHANGE_ALERT=Sensitive change alert
+DESCRIPTION_SENSITIVE_CHANGE_ALERT=Send an alert to the account owner if any sensitive account details are changed in this edit, with your username referenced.
diff --git a/sources/cns_members.php b/sources/cns_members.php
index 5e34af3..978c744 100644
--- a/sources/cns_members.php
+++ b/sources/cns_members.php
@@ -389,7 +389,7 @@ function find_cpf_field_id($title)
 /**
  * Get the ID for a special CPF if we only know the title. Warning: Only use this with custom code, never core code! It assumes a single language and that fields aren't renamed.
  *
- * @param  SHORT_TEXT $title The title.
+ * @param  SHORT_TEXT $title The title, including cms_ prefix.
  * @return ?AUTO_LINK The ID (null: could not find).
  */
 function find_cms_cpf_field_id($title)
diff --git a/sources/cns_members_action2.php b/sources/cns_members_action2.php
index a270236..dc9ea13 100644
--- a/sources/cns_members_action2.php
+++ b/sources/cns_members_action2.php
@@ -713,9 +713,14 @@ function cns_get_member_fields_settings($mini_mode = true, $member_id = null, $g
             if (get_option('enable_highlight_name') == '1') {
                 $fields->attach(form_input_tick(do_lang_tempcode('HIGHLIGHTED_NAME'), do_lang_tempcode(addon_installed('pointstore') ? 'DESCRIPTION_HIGHLIGHTED_NAME_P' : 'DESCRIPTION_HIGHLIGHTED_NAME'), 'highlighted_name', $highlighted_name == 1));
             }
-            if ((!is_null($member_id)) && ($member_id != get_member())) {// Can't ban someone new, and can't ban yourself
+            if ((!is_null($member_id)) && ($member_id != get_member())) { // Can't ban someone new, and can't ban yourself
                 $fields->attach(form_input_tick(do_lang_tempcode('BANNED'), do_lang_tempcode('DESCRIPTION_MEMBER_BANNED'), 'is_perm_banned', $is_perm_banned == 1));
             }
+
+            if (($member_id !== null) && ($member_id != get_member())) {
+                $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('_GUID' => '03452238c372edd0b11c11a05feb6267', 'TITLE' => do_lang_tempcode('ACTIONS'))));
+                $fields->attach(form_input_tick(do_lang_tempcode('SENSITIVE_CHANGE_ALERT'), do_lang_tempcode('DESCRIPTION_SENSITIVE_CHANGE_ALERT'), 'sensitive_change_alert', true));
+            }
         }
 
         if (addon_installed('content_reviews')) {
@@ -876,16 +881,21 @@ function cns_get_member_fields_profile($mini_mode = true, $member_id = null, $gr
  * @param  ?ID_TEXT $password_compatibility_scheme Password compatibility scheme (null: don't change)
  * @param  boolean $skip_checks Whether to skip security checks and most of the change-triggered emails
  */
-function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $dob_month, $dob_year, $timezone, $primary_group, $custom_fields, $theme, $reveal_age, $views_signatures, $auto_monitor_contrib_content, $language, $allow_emails, $allow_emails_from_staff, $validated = null, $username = null, $password = null, $highlighted_name = null, $pt_allow = '*', $pt_rules_text = '', $on_probation_until = null, $auto_mark_read = null, $join_time = null, $avatar_url = null, $signature = null, $is_perm_banned = null, $photo_url = null, $photo_thumb_url = null, $salt = null, $password_compatibility_scheme = null, $skip_checks = false)
+function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $dob_month, $dob_year, $timezone, $primary_group, $custom_fields, $theme, $reveal_age, $views_signatures, $auto_monitor_contrib_content, $language, $allow_emails, $allow_emails_from_staff, $validated = null, $username = null, $password = null, $highlighted_name = null, $pt_allow = '*', $pt_rules_text = '', $on_probation_until = null, $auto_mark_read = null, $join_time = null, $avatar_url = null, $signature = null, $is_perm_banned = null, $photo_url = null, $photo_thumb_url = null, $salt = null, $password_compatibility_scheme = null, $skip_checks = false, $sensitive_change_alert = null)
 {
+    if ($sensitive_change_alert === null) {
+        $sensitive_change_alert = !$skip_checks;
+    }
+
     require_code('type_sanitisation');
     require_code('cns_members_action');
 
     $update = array();
 
-    if (!$skip_checks) {
-        $old_email_address = $GLOBALS['CNS_DRIVER']->get_member_row_field($member_id, 'm_email_address');
+    $old_email_address = $GLOBALS['CNS_DRIVER']->get_member_row_field($member_id, 'm_email_address');
+    $old_username = $GLOBALS['CNS_DRIVER']->get_member_row_field($member_id, 'm_username');
 
+    if (!$skip_checks) {
         $email_address_required = member_field_is_required($member_id, 'email_address');
 
         if ((!is_null($email_address)) && ($email_address != '') && ($email_address != STRING_MAGIC_NULL) && (!is_email_address($email_address))) {
@@ -960,11 +970,21 @@ function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $
     // Set custom profile field values
     $all_fields_types = collapse_2d_complexity('id', 'cf_type', $all_fields);
     $changes = array();
+    $phone_number_field = find_cms_cpf_field_id('cms_mobile_phone_number');
+    if ($phone_number_field !== null) {
+        $phone_number = null;
+        $old_values = $GLOBALS['FORUM_DRIVER']->get_custom_fields($member_id);
+        $old_phone_number = $old_values['mobile_phone_number'];
+    }
     foreach ($custom_fields as $field_id => $value) {
         if (!array_key_exists($field_id, $all_fields_types)) {
             continue; // Trying to set a field we're not allowed to (doesn't apply to our group)
         }
 
+        if ($field_id === $phone_number_field) {
+            $phone_number = $value;
+        }
+
         $change = cns_set_custom_field($member_id, $field_id, $value, $all_fields_types[$field_id], true);
         if (!is_null($change)) {
             $changes = array_merge($changes, $change);
@@ -1051,7 +1071,6 @@ function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $
         $update['m_photo_thumb_url'] = $photo_thumb_url;
     }
 
-    $old_username = $GLOBALS['CNS_DRIVER']->get_member_row_field($member_id, 'm_username');
     if ((!is_null($username)) && (!is_null($old_username)) && ($username != $old_username) && (($skip_checks) || (has_actual_page_access(get_member(), 'admin_cns_members')) || (has_privilege($member_id, 'rename_self')))) { // Username change
         $update['m_username'] = $username;
 
@@ -1070,10 +1089,6 @@ function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $
 
         require_code('notifications');
 
-        $subject = do_lang('USERNAME_CHANGED_MAIL_SUBJECT', $username, $old_username, null, get_lang($member_id));
-        $mail = do_notification_lang('USERNAME_CHANGED_MAIL', comcode_escape(get_site_name()), comcode_escape($username), comcode_escape($old_username), get_lang($member_id));
-        dispatch_notification('cns_username_changed', null, $subject, $mail, array($member_id));
-
         $subject = do_lang('STAFF_USERNAME_CHANGED_MAIL_SUBJECT', $username, $old_username, null, get_site_default_lang());
         $mail = do_notification_lang('STAFF_USERNAME_CHANGED_MAIL', comcode_escape(get_site_name()), comcode_escape($username), comcode_escape($old_username), get_site_default_lang());
         dispatch_notification('cns_username_changed_staff', null, $subject, $mail, null, get_member(), 3, false, false, null, null, '', '', '', '', null, true);
@@ -1087,22 +1102,6 @@ function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $
     if (!is_null($password)) { // Password change
         // Security, clear out sessions from other people on this user - just in case the reset is due to suspicious activity
         $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'sessions WHERE member_id=' . strval($member_id) . ' AND ' . db_string_not_equal_to('the_session', get_session_id()));
-
-        if (!$skip_checks) {
-            if (($member_id == get_member()) || (get_value('disable_password_change_notifications_for_staff') !== '1')) {
-                if (get_page_name() != 'admin_cns_members') {
-                    require_code('notifications');
-
-                    $part_b = '';
-                    if (!has_actual_page_access(get_member(), 'admin_cns_members')) {
-                        $part_b = do_lang('PASSWORD_CHANGED_MAIL_BODY_2', get_ip_address());
-                    }
-                    $mail = do_notification_lang('PASSWORD_CHANGED_MAIL_BODY', get_site_name(), $part_b, null, get_lang($member_id));
-
-                    dispatch_notification('cns_password_changed', null, do_lang('PASSWORD_CHANGED_MAIL_SUBJECT', null, null, null, get_lang($member_id)), $mail, array($member_id), null, 2);
-                }
-            }
-        }
     }
     if (!is_null($validated)) {
         $update['m_validated_email_confirm_code'] = '';
@@ -1144,19 +1143,49 @@ function cns_edit_member($member_id, $email_address, $preview_posts, $dob_day, $
         require_code('mail');
         $_login_url = build_url(array('page' => 'login'), get_module_zone('login'), null, false, false, true);
         $login_url = $_login_url->evaluate();
-        $_username = $GLOBALS['CNS_DRIVER']->get_member_row_field($member_id, 'm_username');
         // NB: Same mail also sent in settings.php (quick-validate feature)
         $vm_subject = do_lang('VALIDATED_MEMBER_SUBJECT', get_site_name(), null, get_lang($member_id));
-        $vm_body = do_lang('MEMBER_VALIDATED', get_site_name(), $_username, $login_url, get_lang($member_id));
-        mail_wrap($vm_subject, $vm_body, array($email_address), $_username, $login_url, '', 3, null, false, null, false, false, false, 'MAIL', false, null, null, $join_time);
+        $vm_body = do_lang('MEMBER_VALIDATED', get_site_name(), $old_username, $login_url, get_lang($member_id));
+        mail_wrap($vm_subject, $vm_body, array($email_address), $old_username, '', '', 2, null, false, null, false, false, false, 'MAIL', false, null, null, $join_time);
     }
 
-    $old_email_address = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_email_address');
-    if ($old_email_address != $email_address) {
-        $GLOBALS['FORUM_DB']->query_update('f_invites', array('i_email_address' => $old_email_address), array('i_email_address' => $email_address));
+    // E-mail OLD e-mail address to inform of sensitive changes
+    $username_changed = ($username !== null) && ($username !== $old_username);
+    $email_address_changed = ($email_address !== null) && ($email_address !== $old_email_address);
+    $password_changed = ($password !== null);
+    $phone_number_changed = ($phone_number_field !== null) && ($phone_number !== null) && ($old_phone_number !== $phone_number);
+    if (($username_changed || $email_address_changed || $password_changed || $phone_number_changed) && ($sensitive_change_alert)) {
+        $current_username = $GLOBALS['FORUM_DRIVER']->get_username(get_member());
+
+        $_sensitive_changes = array();
+        if ($username_changed) {
+            $_sensitive_changes[] = do_lang('SECURITY_ASPECT_CHANGED__USERNAME', $old_username, $username);
+        }
+        if ($email_address_changed) {
+            $_sensitive_changes[] = do_lang('SECURITY_ASPECT_CHANGED__EMAIL_ADDRESS', $old_email_address, $email_address);
+        }
+        if ($password_changed) {
+            $_sensitive_changes[] = do_lang('SECURITY_ASPECT_CHANGED__PASSWORD');
+        }
+        if ($phone_number_changed) {
+            $_sensitive_changes[] = do_lang('SECURITY_ASPECT_CHANGED__PHONE_NUMBER', $old_phone_number, $phone_number);
+        }
+        $sensitive_changes = implode("\n", $_sensitive_changes);
+
+        $part_b = '';
+        if (!has_actual_page_access(get_member(), 'admin_cns_members')) { // If change not by an admin
+            $part_b = do_lang('SECURITY_ASPECT_CHANGED_BODY_2', get_ip_address());
+        }
+
+        $cm_subject = do_lang('SECURITY_ASPECT_CHANGED_SUBJECT', $old_username, $current_username, array(get_site_name()));
+        $cm_body = do_lang('SECURITY_ASPECT_CHANGED_BODY', $old_username, $current_username, array(get_site_name(), $sensitive_changes, $part_b));
+
+        if ($old_email_address != '') {
+            require_code('mail');
+            mail_wrap($cm_subject, $cm_body, array($old_email_address), $old_username, '', '', 1, null, false, null, false, false, false, 'MAIL', true, null, null, $join_time);
+        }
     }
 
-    $old_email_address = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_email_address');
     if ($old_email_address != $email_address) {
         $GLOBALS['FORUM_DB']->query_update('f_invites', array('i_email_address' => $old_email_address), array('i_email_address' => $email_address));
     }
diff --git a/sources/hooks/systems/addon_registry/core_cns.php b/sources/hooks/systems/addon_registry/core_cns.php
index 6b4ad15..501d414 100644
--- a/sources/hooks/systems/addon_registry/core_cns.php
+++ b/sources/hooks/systems/addon_registry/core_cns.php
@@ -154,7 +154,6 @@ class Hook_addon_registry_core_cns
             'sources/hooks/systems/content_meta_aware/topic.php',
             'sources/hooks/systems/content_meta_aware/post.php',
             'sources/hooks/modules/admin_import/emoticons.php',
-            'sources/hooks/systems/notifications/cns_password_changed.php',
             'sources/hooks/systems/snippets/member_tooltip.php',
             'sources/hooks/systems/notifications/cns_rank_promoted.php',
             'sources/hooks/systems/snippets/exists_email.php',
@@ -191,7 +190,6 @@ class Hook_addon_registry_core_cns
             'sources/hooks/systems/config/require_new_member_validation.php',
             'sources/hooks/systems/config/restricted_usernames.php',
             'sources/hooks/systems/config/show_first_join_page.php',
-            'sources/hooks/systems/notifications/cns_username_changed.php',
             'sources/hooks/systems/notifications/cns_group_join_request.php',
             'sources/hooks/systems/notifications/cns_group_declined.php',
             'sources/hooks/systems/notifications/cns_birthday.php',
diff --git a/sources/hooks/systems/notifications/cns_password_changed.php b/sources/hooks/systems/notifications/cns_password_changed.php
deleted file mode 100644
index f4dad7e..0000000
--- a/sources/hooks/systems/notifications/cns_password_changed.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php /*
-
- Composr
- Copyright (c) ocProducts, 2004-2016
-
- See text/EN/licence.txt for full licencing information.
-
-
- NOTE TO PROGRAMMERS:
-   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
-   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****
-
-*/
-
-/**
- * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
- * @copyright  ocProducts Ltd
- * @package    core_cns
- */
-
-/**
- * Hook class.
- */
-class Hook_notification_cns_password_changed extends Hook_Notification
-{
-    /**
-     * Get a list of all the notification codes this hook can handle.
-     * (Addons can define hooks that handle whole sets of codes, so hooks are written so they can take wide authority)
-     *
-     * @return array List of codes (mapping between code names, and a pair: section and labelling for those codes)
-     */
-    public function list_handled_codes()
-    {
-        $list = array();
-        $list['cns_password_changed'] = array(do_lang('MEMBERS'), do_lang('cns:NOTIFICATION_TYPE_cns_password_changed'));
-        return $list;
-    }
-}
diff --git a/sources/hooks/systems/notifications/cns_username_changed.php b/sources/hooks/systems/notifications/cns_username_changed.php
deleted file mode 100644
index 13dc39d..0000000
--- a/sources/hooks/systems/notifications/cns_username_changed.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php /*
-
- Composr
- Copyright (c) ocProducts, 2004-2016
-
- See text/EN/licence.txt for full licencing information.
-
-
- NOTE TO PROGRAMMERS:
-   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
-   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****
-
-*/
-
-/**
- * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
- * @copyright  ocProducts Ltd
- * @package    core_cns
- */
-
-/**
- * Hook class.
- */
-class Hook_notification_cns_username_changed extends Hook_Notification
-{
-    /**
-     * Get a list of all the notification codes this hook can handle.
-     * (Addons can define hooks that handle whole sets of codes, so hooks are written so they can take wide authority)
-     *
-     * @return array List of codes (mapping between code names, and a pair: section and labelling for those codes)
-     */
-    public function list_handled_codes()
-    {
-        $list = array();
-        $list['cns_username_changed'] = array(do_lang('MEMBERS'), do_lang('cns:NOTIFICATION_TYPE_cns_username_changed'));
-        return $list;
-    }
-}
diff --git a/sources/hooks/systems/profiles_tabs_edit/settings.php b/sources/hooks/systems/profiles_tabs_edit/settings.php
index 121cdbd..c42ad25 100644
--- a/sources/hooks/systems/profiles_tabs_edit/settings.php
+++ b/sources/hooks/systems/profiles_tabs_edit/settings.php
@@ -193,7 +193,12 @@ class Hook_profiles_tabs_edit_settings
                 }
             }
 
-            cns_edit_member($member_id_of, $email_address, $preview_posts, $dob_day, $dob_month, $dob_year, $timezone, $primary_group, $actual_custom_fields, $theme, post_param_integer('reveal_age', fractional_edit() ? INTEGER_MAGIC_NULL : 0), $views_signatures, $auto_monitor_contrib_content, post_param_string('language', fractional_edit() ? STRING_MAGIC_NULL : null), post_param_integer('allow_emails', fractional_edit() ? INTEGER_MAGIC_NULL : 0), post_param_integer('allow_emails_from_staff', fractional_edit() ? INTEGER_MAGIC_NULL : 0), $validated, $username, $password, $highlighted_name, $pt_allow, $pt_rules_text, $on_probation_until, $auto_mark_read);
+            $sensitive_change_alert = true;
+            if ((has_privilege($member_id_viewing, 'member_maintenance')) && ($member_id_viewing != $member_id_of) && (post_param_integer('sensitive_change_alert', 0) == 0)) {
+                $sensitive_change_alert = false;
+            }
+
+            cns_edit_member($member_id_of, $email_address, $preview_posts, $dob_day, $dob_month, $dob_year, $timezone, $primary_group, $actual_custom_fields, $theme, post_param_integer('reveal_age', fractional_edit() ? INTEGER_MAGIC_NULL : 0), $views_signatures, $auto_monitor_contrib_content, post_param_string('language', fractional_edit() ? STRING_MAGIC_NULL : null), post_param_integer('allow_emails', fractional_edit() ? INTEGER_MAGIC_NULL : 0), post_param_integer('allow_emails_from_staff', fractional_edit() ? INTEGER_MAGIC_NULL : 0), $validated, $username, $password, $highlighted_name, $pt_allow, $pt_rules_text, $on_probation_until, $auto_mark_read, null, null, null, null, null, null, null, null, false, $sensitive_change_alert);
 
             if (addon_installed('content_reviews')) {
                 require_code('content_reviews2');
sensitive-changed.diff (22,979 bytes)   
Time estimation (hours)1
Sponsorship open

Sponsor

Date Added Member Amount Sponsored

Relationships

related to 1269 Not AssignedGuest Password-sharing prevention 
related to 1276 Not AssignedGuest Show login history 
related to 4903 ResolvedPDStig Logging if a member username or email address is changed 

Activities

Chris Graham

2021-02-04 21:20

administrator   ~6934

Implemented this for a client, so I have a patch. But I don't want any distractions from getting v11 done, so I'm not going to worry about merging that patch until after v11 is done.

Issue History

Date Modified Username Field Change
2017-03-25 13:55 Chris Graham New Issue
2017-03-25 13:55 Chris Graham Tag Attached: Type: Security
2017-03-25 13:55 Chris Graham Relationship added related to 1269
2017-03-25 13:55 Chris Graham Relationship added related to 1276
2021-01-27 18:06 Chris Graham Summary E-mails upon login => E-mails upon login/change password/change email address
2021-01-27 18:06 Chris Graham Description Updated
2021-01-27 18:17 Chris Graham Time estimation (hours) 0.5 => 1
2021-02-04 21:20 Chris Graham Tag Attached: Roadmap: v12
2021-02-04 21:20 Chris Graham Note Added: 0006934
2021-07-23 22:38 Chris Graham Assigned To => user4172
2021-07-23 22:38 Chris Graham Status Not Assigned => Assigned
2021-11-01 20:12 Chris Graham Tag Attached: Has Patch
2021-11-01 20:22 Chris Graham File Added: sensitive-changed.diff
2022-08-15 16:57 Chris Graham Tag Detached: Roadmap: v12
2022-08-15 16:57 Chris Graham Tag Attached: Roadmap: v11
2022-10-06 00:23 Chris Graham Relationship added related to 4903
2022-10-19 00:47 PDStig Status Assigned => Resolved
2022-10-19 00:47 PDStig Resolution open => fixed