View Issue Details

IDProjectCategoryView StatusLast Update
0010207mantisbtemailpublic2017-09-12 19:49
Reporterwolog Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status feedbackResolutionopen 
Product Version1.1.1 
Summary0010207: Allow multiple valids emails address per account (patch attached)
Description

Some users here ask to have more than one email address attached to their mantis account. (f.e. some subcontractors wants only one accounts, but several people wants to be notified)

The patch below allow this behaviour. You just have to put multiple address separated by semicolon in the E-mail field. The validations rules are kept (each address is checked as usual). The 'lost password' procedure is updated to accept any of the recorded valid address. All notifications are send to all emails addresses.

  • You may need to change the email field size in database ('only' 64 chars by default)

Known (little) Bug:

  • The verification query in 'lost password' is too permissive. (It will match a partial email address: 'e@domain.tld' will match 'me@domain.tld').
Tagspatch
Attached Files
0001-multiples-email-adresses-per-mantis-account.patch (4,554 bytes)   
From: Olivier Guerrier <olivier@guerrier.com>
Date: Sun, 15 Mar 2009 01:05:13 +0100
Subject: [PATCH] multiples email adresses per mantis account

---
 mantis-1.1.1/core/email_api.php |   85 ++++++++++++++++++-------------
 mantis-1.1.1/lost_pwd.php       |    2 +-
 2 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/mantis-1.1.1/core/email_api.php b/mantis-1.1.1/core/email_api.php
index ea0eafe..dbef9d2 100644
--- a/mantis-1.1.1/core/email_api.php
+++ b/mantis-1.1.1/core/email_api.php
@@ -123,46 +123,53 @@
 
 		# Use a regular expression to check to see if the email is in valid format
 		#  x-xx.xxx@yyy.zzz.abc etc.
-		if ( preg_match( email_get_rfc822_regex(), $p_email, $t_check ) ) {
-			$t_local = $t_check[1];
-			$t_domain = $t_check[2];
-
-			# see if we're limited to one domain
-			if ( ON == config_get( 'limit_email_domain' ) ) {
-				if ( 0 != strcasecmp( $t_limit_email_domain, $t_domain ) ) {
-					return false;
+		$t_split_emails = split (';', $p_email);
+		foreach($t_split_emails as $t_split_email) {
+			$t_split_email_ok = false;
+			if ( preg_match( email_get_rfc822_regex(), $t_split_email, $t_check ) ) {
+				$t_local = $t_check[1];
+				$t_domain = $t_check[2];
+
+				# see if we're limited to one domain
+				if ( ON == config_get( 'limit_email_domain' ) ) {
+					if ( 0 != strcasecmp( $t_limit_email_domain, $t_domain ) ) {
+						return false;
+					}
 				}
-			}
 
-			if ( preg_match( '/\\[(\d+)\.(\d+)\.(\d+)\.(\d+)\\]/', $t_domain, $t_check ) ) {
-				# Handle domain-literals of the form '[1.2.3.4]'
-				#  as long as each segment is less than 255, we're ok
-				if ( $t_check[1] <= 255 &&
-					 $t_check[2] <= 255 &&
-					 $t_check[3] <= 255 &&
-					 $t_check[4] <= 255 ) {
-					return true;
-				}
-			} else if ( ON == config_get( 'check_mx_record' ) ) {
-				# Check for valid mx records
-				if ( getmxrr( $t_domain, $temp ) ) {
-					return true;
-				} else {
-					$host = $t_domain . '.';
-
-					# for no mx record... try dns check
-					if ( checkdnsrr( $host, 'ANY' ) ) {
-						return true;
+				if ( preg_match( '/\\[(\d+)\.(\d+)\.(\d+)\.(\d+)\\]/', $t_domain, $t_check ) ) {
+					# Handle domain-literals of the form '[1.2.3.4]'
+					#  as long as each segment is less than 255, we're ok
+					if ( $t_check[1] <= 255 &&
+						 $t_check[2] <= 255 &&
+						 $t_check[3] <= 255 &&
+						 $t_check[4] <= 255 ) {
+						$t_split_email_ok = true;
+					}
+				} else if ( ON == config_get( 'check_mx_record' ) ) {
+					# Check for valid mx records
+					if ( getmxrr( $t_domain, $temp ) ) {
+						$t_split_email_ok = true;
+					} else {
+						$host = $t_domain . '.';
+
+						# for no mx record... try dns check
+						if ( checkdnsrr( $host, 'ANY' ) ) {
+							$t_split_email_ok = true;
+						}
 					}
+				} else {
+					# Email format was valid but did't check for valid mx records
+					$t_split_email_ok = true;
 				}
-			} else {
-				# Email format was valid but did't check for valid mx records
-				return true;
+			}
+			if ( $t_split_email_ok == false ) {
+				# Everything failed.  The email is invalid
+				return false;
 			}
 		}
-
-		# Everything failed.  The email is invalid
-		return false;
+		# all addresses are valid
+		return true;
 	}
 	# --------------------
 	# Check if the email address is valid
@@ -780,9 +787,15 @@
 
 		if ( OFF !== $t_debug_email ) {
 			$t_message = 'To: '. $t_recipient . "\n\n" . $t_message;
-			$mail->AddAddress( $t_debug_email, '' );
+			$t_split_recipients = split (';', $t_debug_email);
+			foreach($t_split_recipients as $t_split_recipient) {
+				$mail->AddAddress( $t_split_recipient, '' );
+			}
 		} else {
-			$mail->AddAddress( $t_recipient, '' );
+			$t_split_recipients = split (';', $t_recipient);
+			foreach($t_split_recipients as $t_split_recipient) {
+				$mail->AddAddress( $t_split_recipient, '' );
+			}
 		}
 
 		$mail->Subject = $t_subject;
diff --git a/mantis-1.1.1/lost_pwd.php b/mantis-1.1.1/lost_pwd.php
index 7672232..360ca34 100644
--- a/mantis-1.1.1/lost_pwd.php
+++ b/mantis-1.1.1/lost_pwd.php
@@ -51,7 +51,7 @@
 	$t_user_table = config_get( 'mantis_user_table' );
 
 	# @@@ Consider moving this query to user_api.php
-	$query = 'SELECT id FROM ' . $t_user_table . ' WHERE username = \'' . $c_username . '\' AND email = \'' . $c_email . '\' AND enabled=1';
+	$query = 'SELECT id FROM ' . $t_user_table . ' WHERE username = \'' . $c_username . '\' AND email LIKE \'%' . $c_email . '%\' AND enabled=1';
 	$result = db_query( $query );
 
 	if ( 0 == db_num_rows( $result ) ) {
-- 
1.6.2

0002-multiples-email-adresses-per-mantis-account-rev1.patch (6,530 bytes)   
diff --git a/core/email_api.php b/core/email_api.php
index b01286e..08f39cc 100644
--- a/core/email_api.php
+++ b/core/email_api.php
@@ -159,49 +159,54 @@ function email_is_valid( $p_email ) {
 
 	# Use a regular expression to check to see if the email is in valid format
 	#  x-xx.xxx@yyy.zzz.abc etc.
-	if( preg_match( email_get_rfc822_regex(), $p_email, $t_check ) ) {
-		$t_local = $t_check[1];
-		$t_domain = $t_check[2];
-
-		# see if we're limited to one domain
-		$t_limit_email_domain = config_get( 'limit_email_domain' ); 
-		if( $t_limit_email_domain !== OFF  ) {
-			if( 0 != strcasecmp( $t_limit_email_domain, $t_domain ) ) {
-				return false;
+	$t_split_emails = split (';', $p_email);
+	foreach($t_split_emails as $t_split_email) {
+		$t_split_email_ok = false;
+		if ( preg_match( email_get_rfc822_regex(), $t_split_email, $t_check ) ) {
+			$t_local = $t_check[1];
+			$t_domain = $t_check[2];
+	
+			# see if we're limited to one domain
+			if ( ON == config_get( 'limit_email_domain' ) ) {
+				if ( 0 != strcasecmp( $t_limit_email_domain, $t_domain ) ) {
+					return false;
+				}
 			}
-		}
-
-		if( preg_match( '/\\[(\d+)\.(\d+)\.(\d+)\.(\d+)\\]/', $t_domain, $t_check ) ) {
-
+	
+			if ( preg_match( '/\\[(\d+)\.(\d+)\.(\d+)\.(\d+)\\]/', $t_domain, $t_check ) ) {
 			# Handle domain-literals of the form '[1.2.3.4]'
 			#  as long as each segment is less than 255, we're ok
-			if( $t_check[1] <= 255 && $t_check[2] <= 255 && $t_check[3] <= 255 && $t_check[4] <= 255 ) {
-				return true;
-			}
-		}
-		elseif( ON == config_get( 'check_mx_record' ) ) {
-			$temp = '';
-
-			# Check for valid mx records
-			if( getmxrr( $t_domain, $temp ) ) {
-				return true;
-			} else {
-				$host = $t_domain . '.';
-
-				# for no mx record... try dns check
-				if( checkdnsrr( $host, 'ANY' ) ) {
-					return true;
+				if ( $t_check[1] <= 255 &&
+						$t_check[2] <= 255 &&
+						$t_check[3] <= 255 &&
+						$t_check[4] <= 255 ) {
+					$t_split_email_ok = true;
+					}
+			} else if ( ON == config_get( 'check_mx_record' ) ) {
+				# Check for valid mx records
+				if ( getmxrr( $t_domain, $temp ) ) {
+					$t_split_email_ok = true;
+				} else {
+					$host = $t_domain . '.';
+	
+					# for no mx record... try dns check
+					if ( checkdnsrr( $host, 'ANY' ) ) {
+						$t_split_email_ok = true;
+					}
 				}
+			} else {
+				# Email format was valid but did't check for valid mx records
+				$t_split_email_ok = true;
 			}
-		} else {
-
-			# Email format was valid but did't check for valid mx records
-			return true;
+		}
+		if ( $t_split_email_ok == false ) {
+			# Everything failed.  The email is invalid
+			return false;
 		}
 	}
 
-	# Everything failed.  The email is invalid
-	return false;
+	# all addresses are valid
+	return true;
 }
 
 # Check if the email address is valid
@@ -821,9 +826,15 @@ function email_send( $p_email_data ) {
 
 	if( OFF !== $t_debug_email ) {
 		$t_message = 'To: ' . $t_recipient . "\n\n" . $t_message;
-		$mail->AddAddress( $t_debug_email, '' );
+		$t_split_recipients = split (';', $t_debug_email);
+		foreach($t_split_recipients as $t_split_recipient) {
+			$mail->AddAddress( $t_split_recipient, '' );
+		}
 	} else {
-		$mail->AddAddress( $t_recipient, '' );
+		$t_split_recipients = split (';', $t_recipient);
+		foreach($t_split_recipients as $t_split_recipient) {
+			$mail->AddAddress( $t_split_recipient, '' );
+		}
 	}
 
 	$mail->Subject = $t_subject;
@@ -915,7 +926,8 @@ function make_lf_crlf( $p_string ) {
  */
 function email_append_domain( $p_email ) {
 	# If email is empty or already contains a domain, then return as is.
-	if ( is_blank( $p_email ) || strchr( $p_email, '@' ) ) {
+	# If email contains multiple addresses, then return as is.
+	if ( is_blank( $p_email ) || strchr( $p_email, '@' ) || strchr( $p_email, ';' ) ) {
 		return $p_email;
 	}
 
diff --git a/core/print_api.php b/core/print_api.php
index a27a811..487129b 100644
--- a/core/print_api.php
+++ b/core/print_api.php
@@ -193,13 +193,17 @@ function print_user_with_subject( $p_user_id, $p_bug_id ) {
 # print out an email editing input
 function print_email_input( $p_field_name, $p_email ) {
 	$t_limit_email_domain = config_get( 'limit_email_domain' );
-	if( $t_limit_email_domain ) {
-
-		# remove the domain part
-		$p_email = eregi_replace( "@$t_limit_email_domain$", '', $p_email );
-		echo '<input type="text" name="' . $p_field_name . '" size="20" maxlength="64" value="' . $p_email . '" />@' . $t_limit_email_domain;
+	if( strchr($p_email, ';' ) ) {
+		echo '<textarea name="' . $p_field_name . '" cols="64" rows="4" >' . $p_email . '</textarea>';
 	} else {
-		echo '<input type="text" name="' . $p_field_name . '" size="32" maxlength="64" value="' . $p_email . '" />';
+		if( $t_limit_email_domain ) {
+
+			# remove the domain part
+			$p_email = eregi_replace( "@$t_limit_email_domain$", '', $p_email );
+			echo '<input type="text" name="' . $p_field_name . '" size="20" maxlength="64" value="' . $p_email . '" />@' . $t_limit_email_domain;
+		} else {
+			echo '<input type="text" name="' . $p_field_name . '" size="32" maxlength="256" value="' . $p_email . '" />';
+		}
 	}
 }
 
diff --git a/lost_pwd.php b/lost_pwd.php
index c50501e..a3295f7 100644
--- a/lost_pwd.php
+++ b/lost_pwd.php
@@ -45,12 +45,15 @@
 
 	$f_email = email_append_domain( $f_email );
 	email_ensure_valid( $f_email );
+	
+	$c_username = db_prepare_string( $f_username );
+	$c_email = db_prepare_string( $f_email );
 
 	$t_user_table = db_get_table( 'mantis_user_table' );
 
 	/** @todo Consider moving this query to user_api.php */
-	$query = 'SELECT id FROM ' . $t_user_table . ' WHERE username = ' . db_param() . ' AND email = ' . db_param() . ' AND enabled=' . db_param();
-	$result = db_query_bound( $query, Array( $f_username, $f_email, true ) );
+	$query = 'SELECT id,email FROM ' . $t_user_table . ' WHERE username = \'' . $c_username . '\' AND enabled=1';
+	$result = db_query( $query );
 
 	if ( 0 == db_num_rows( $result ) ) {
 		trigger_error( ERROR_LOST_PASSWORD_NOT_MATCHING_DATA, ERROR );
@@ -62,6 +65,17 @@
 
 	$row = db_fetch_array( $result );
 	$t_user_id = $row['id'];
+	$t_split_emails = split (';', $row['email']);
+	$t_email_error = true;
+	foreach($t_split_emails as $t_split_email) {
+		if($c_email == $t_split_email) {
+			$t_email_error = false;
+			break;
+		}
+	}
+	if ($t_email_error) {
+		trigger_error( ERROR_LOST_PASSWORD_NOT_MATCHING_DATA, ERROR );
+	}
 
 	if( user_is_protected( $t_user_id ) ) {
 		trigger_error( ERROR_PROTECTED_ACCOUNT, ERROR );

Relationships

related to 0011475 new Merging users and multiple email addresses per user 
has duplicate 0005116 closedatrol alternative e-mail for user 
has duplicate 0021226 closedatrol Multiple valids emails address per account in 1.2.19 Mantisbt 
has duplicate 0023347 closedatrol multiple emails for a user 
has duplicate 0023348 closedatrol emails with separator for users 
related to 0005081 acknowledged Assigning multiple persons to an issue 
related to 0006644 closedgrangeway Patch for multiple developers per issue 
related to 0019977 new Add event "SENT_BUG_INFO_TO_ONE_USER" 

Activities

siebrand

siebrand

2009-03-28 14:06

developer   ~0021251

You mention the following known issue:

  • The verification query in 'lost password' is too permissive. (It will match a partial email address: 'e@domain.tld' will match 'me@domain.tld'

Please clarify. Does that issue exist now, or after applying this patch? If so, this patch is insufficient and will be denied.

wolog

wolog

2009-03-28 18:09

reporter   ~0021254

before applying this patch, mantis want a perfect match between the login and the email adress (easy to check as we have only one email adress per account).

Here is the query used by mantis before the patch:
SELECT id FROM $t_user_table WHERE username = '$c_username' AND email = '$c_email' AND enabled=1

after applying the patch, as we may have several email address per account, the former query will not work, (unless you give all the associated emails address, in the correct order...). So I change the query to allow only a partial match:

SELECT id FROM $t_user_table WHERE username = '$c_username' AND email LIKE '%$c_email%' AND enabled=1

Please note this modification only affect the validation procedure on the form, if there is a match (even partial) the mails are send only to the registered address, and never to the address given on the form.

also note that the given data must be a valid email (it is impossible to give only a single letter like 'e' or only a tld '.com')

Anyway, I admit this not the best way to go (this is the reason I mention this issue).

I didn't think this patch could go in mainstream, but if this issue is the only detail preventing this to happen, I can make a better check, to get the same behaviour as before.

siebrand

siebrand

2009-03-28 18:33

developer   ~0021255

I'm fine with the feature. I suggest you read out the e-mail addresses from the database, explode them into an array, and then check if the given address matches one of the array elements. It is a bit more expensive, but nothing to worry about.

siebrand

siebrand

2009-03-28 18:35

developer   ~0021256

Last edited: 2009-03-30 12:03

Oh, another thing. You apparently made the patch for 1.1.1. It should be for git master: http://git.mantisbt.org/?p=mantisbt.git;a=tree.

(removed comment about backporting to 1.1.x - not doing that)

jreese

jreese

2009-03-28 18:37

reporter   ~0021257

As a note, any new features like this can only go into development releases like 1.2.x (git master). Maintenance versions such as 1.1.7 are only open for bug fixes.

wolog

wolog

2009-07-08 18:56

reporter   ~0022454

The new patch should address all comments:

  • it is against 1.2.0a3
  • lost_pwd works as expected (one of the emails must match exactly)

Also Added:

  • the field in manage_user_edit_page.php is changed to a textarea, only if multiples emails are used
  • limit_email_domain config option should work, but not tested (you must type the domain in all addresses, but the test should pass)

Change not included in the patch:

  • The database field mantis_user_table.email should be changed to something longer. I use varchar(256).
waldemar

waldemar

2010-09-06 09:38

reporter   ~0026587

I just installed Version 1.2.2, and it is possible to put multiple address separated by semicolon in the E-mail field, but the emails aren't sent if I use more than one address.

Should this work in Version 1.2.2? Or do I still need a patch?

Thank you for any help...

afite

afite

2011-04-07 12:05

reporter   ~0028559

Last edited: 2011-04-07 12:55

I've tested version 1.2.5, with multiple address separated by semicolon in the E-mail field, but the emails still aren't sent.

jazz

jazz

2016-07-07 03:17

reporter   ~0053521

Its not working... Email are bnot being sent .
Can anyone update me on this feature.

I want to register multiple email id for one account.We are using one generic account for each team.Hence one account may need to register with 4-5 email IDs.

ISELA CHAVEZ

ISELA CHAVEZ

2017-09-12 19:40

reporter   ~0057706

any patch for Mantis BT 2.6.0