- Support contact's email addresses up to 255 characters long (#1487095)

- Added email format checks when saving contacts data
release-0.6
alecpl 14 years ago
parent d366462316
commit 6f096812c9

@ -58,6 +58,7 @@ CHANGELOG Roundcube Webmail
- Plugin API: add possibility to disable plugin in framed mode, 'noframe' property - Plugin API: add possibility to disable plugin in framed mode, 'noframe' property
- Improve performance of setting IMAP flags using .SILENT suffix - Improve performance of setting IMAP flags using .SILENT suffix
- Improve performance of message cache status checking with skip_disabled=true - Improve performance of message cache status checking with skip_disabled=true
- Support contact's email addresses up to 255 characters long (#1487095)
RELEASE 0.4.2 RELEASE 0.4.2
------------- -------------

@ -13,7 +13,7 @@ CREATE TABLE [dbo].[contacts] (
[changed] [datetime] NOT NULL , [changed] [datetime] NOT NULL ,
[del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL , [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
[name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL , [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[email] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL , [email] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
[firstname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL , [firstname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[surname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL , [surname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[vcard] [text] COLLATE Latin1_General_CI_AI NULL [vcard] [text] COLLATE Latin1_General_CI_AI NULL

@ -22,7 +22,7 @@ ALTER TABLE [dbo].[identities] ADD CONSTRAINT [FK_identities_user_id]
ON DELETE CASCADE ON UPDATE CASCADE ON DELETE CASCADE ON UPDATE CASCADE
GO GO
ALTER TABLE [dbo].[identities] add [changed] [datetime] NULL ALTER TABLE [dbo].[identities] ADD [changed] [datetime] NULL
GO GO
CREATE TABLE [dbo].[contactgroups] ( CREATE TABLE [dbo].[contactgroups] (
@ -93,4 +93,6 @@ DROP INDEX [IX_users_username]
GO GO
CREATE UNIQUE INDEX [IX_users_username] ON [dbo].[users]([username],[mail_host]) ON [PRIMARY] CREATE UNIQUE INDEX [IX_users_username] ON [dbo].[users]([username],[mail_host]) ON [PRIMARY]
GO GO
ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL
GO

@ -83,7 +83,7 @@ CREATE TABLE `contacts` (
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`del` tinyint(1) NOT NULL DEFAULT '0', `del` tinyint(1) NOT NULL DEFAULT '0',
`name` varchar(128) NOT NULL DEFAULT '', `name` varchar(128) NOT NULL DEFAULT '',
`email` varchar(128) NOT NULL, `email` varchar(255) NOT NULL,
`firstname` varchar(128) NOT NULL DEFAULT '', `firstname` varchar(128) NOT NULL DEFAULT '',
`surname` varchar(128) NOT NULL DEFAULT '', `surname` varchar(128) NOT NULL DEFAULT '',
`vcard` text NULL, `vcard` text NULL,

@ -129,3 +129,5 @@ UPDATE `users` SET `last_login` = NULL WHERE `last_login` = '1000-01-01 00:00:00
ALTER TABLE `users` DROP INDEX `username_index`; ALTER TABLE `users` DROP INDEX `username_index`;
ALTER TABLE `users` ADD UNIQUE `username` (`username`, `mail_host`); ALTER TABLE `users` ADD UNIQUE `username` (`username`, `mail_host`);
ALTER TABLE `contacts` MODIFY `email` varchar(255) NOT NULL;

@ -107,7 +107,7 @@ CREATE TABLE contacts (
changed timestamp with time zone DEFAULT now() NOT NULL, changed timestamp with time zone DEFAULT now() NOT NULL,
del smallint DEFAULT 0 NOT NULL, del smallint DEFAULT 0 NOT NULL,
name varchar(128) DEFAULT '' NOT NULL, name varchar(128) DEFAULT '' NOT NULL,
email varchar(128) DEFAULT '' NOT NULL, email varchar(255) DEFAULT '' NOT NULL,
firstname varchar(128) DEFAULT '' NOT NULL, firstname varchar(128) DEFAULT '' NOT NULL,
surname varchar(128) DEFAULT '' NOT NULL, surname varchar(128) DEFAULT '' NOT NULL,
vcard text vcard text

@ -86,4 +86,5 @@ ALTER TABLE users ALTER last_login SET DEFAULT NULL;
DROP INDEX users_username_id_idx; DROP INDEX users_username_id_idx;
ALTER TABLE users ADD UNIQUE (username, mail_host); ALTER TABLE users ADD UNIQUE (username, mail_host);
ALTER TABLE contacts ALTER email TYPE varchar(255);

@ -28,7 +28,7 @@ CREATE TABLE contacts (
changed datetime NOT NULL default '0000-00-00 00:00:00', changed datetime NOT NULL default '0000-00-00 00:00:00',
del tinyint NOT NULL default '0', del tinyint NOT NULL default '0',
name varchar(128) NOT NULL default '', name varchar(128) NOT NULL default '',
email varchar(128) NOT NULL default '', email varchar(255) NOT NULL default '',
firstname varchar(128) NOT NULL default '', firstname varchar(128) NOT NULL default '',
surname varchar(128) NOT NULL default '', surname varchar(128) NOT NULL default '',
vcard text NOT NULL default '' vcard text NOT NULL default ''

@ -146,3 +146,37 @@ DROP TABLE tmp_users;
DROP INDEX ix_users_username; DROP INDEX ix_users_username;
CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host); CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
CREATE TABLE contacts_tmp (
contact_id integer NOT NULL PRIMARY KEY,
user_id integer NOT NULL default '0',
changed datetime NOT NULL default '0000-00-00 00:00:00',
del tinyint NOT NULL default '0',
name varchar(128) NOT NULL default '',
email varchar(255) NOT NULL default '',
firstname varchar(128) NOT NULL default '',
surname varchar(128) NOT NULL default '',
vcard text NOT NULL default ''
);
INSERT INTO contacts_tmp (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts;
DROP TABLE contacts;
CREATE TABLE contacts (
contact_id integer NOT NULL PRIMARY KEY,
user_id integer NOT NULL default '0',
changed datetime NOT NULL default '0000-00-00 00:00:00',
del tinyint NOT NULL default '0',
name varchar(128) NOT NULL default '',
email varchar(255) NOT NULL default '',
firstname varchar(128) NOT NULL default '',
surname varchar(128) NOT NULL default '',
vcard text NOT NULL default ''
);
INSERT INTO contacts (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts_tmp;
CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
DROP TABLE contacts_tmp;

@ -491,12 +491,11 @@ function rcube_check_email(input, inline)
quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22', quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22',
// Use simplified domain matching, because we need to allow Unicode characters here // Use simplified domain matching, because we need to allow Unicode characters here
// So, e-mail address should be validated also on server side after idn_to_ascii() use // So, e-mail address should be validated also on server side after idn_to_ascii() use
sub_domain = '[^@]+',
//domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d', //domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d',
//sub_domain = '('+atom+'|'+domain_literal+')', //sub_domain = '('+atom+'|'+domain_literal+')',
domain = '([^@\\x2e]+\\x2e)+[a-z]{2,}',
word = '('+atom+'|'+quoted_string+')', word = '('+atom+'|'+quoted_string+')',
delim = '[,;\s\n]', delim = '[,;\s\n]',
domain = sub_domain+'(\\x2e'+sub_domain+')*',
local_part = word+'(\\x2e'+word+')*', local_part = word+'(\\x2e'+word+')*',
addr_spec = local_part+'\\x40'+domain, addr_spec = local_part+'\\x40'+domain,
reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i'); reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');

@ -20,19 +20,17 @@
*/ */
$cid = get_input_value('_cid', RCUBE_INPUT_POST); $cid = get_input_value('_cid', RCUBE_INPUT_POST);
$return_action = empty($cid) ? 'add' : 'show'; $return_action = empty($cid) ? 'add' : 'edit';
// cannot edit record // cannot edit record
if ($CONTACTS->readonly) if ($CONTACTS->readonly) {
{
$OUTPUT->show_message('contactreadonly', 'error'); $OUTPUT->show_message('contactreadonly', 'error');
rcmail_overwrite_action($return_action); rcmail_overwrite_action($return_action);
return; return;
} }
// check input // Basic input checks
if ((!get_input_value('_name', RCUBE_INPUT_POST) || !get_input_value('_email', RCUBE_INPUT_POST))) if ((!get_input_value('_name', RCUBE_INPUT_POST) || !get_input_value('_email', RCUBE_INPUT_POST))) {
{
$OUTPUT->show_message('formincomplete', 'warning'); $OUTPUT->show_message('formincomplete', 'warning');
rcmail_overwrite_action($return_action); rcmail_overwrite_action($return_action);
return; return;
@ -44,20 +42,27 @@ $a_save_cols = array('name', 'firstname', 'surname', 'email');
$a_record = array(); $a_record = array();
// read POST values into hash array // read POST values into hash array
foreach ($a_save_cols as $col) foreach ($a_save_cols as $col) {
{
$fname = '_'.$col; $fname = '_'.$col;
if (isset($_POST[$fname])) if (isset($_POST[$fname]))
$a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST); $a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST);
} }
// Validity checks
$_email = idn_to_ascii($a_record['email']);
if (!check_email($_email, false)) {
$OUTPUT->show_message('emailformaterror', 'warning', array('email' => $_email));
rcmail_overwrite_action($return_action);
return;
}
// update an existing contact // update an existing contact
if (!empty($cid)) if (!empty($cid))
{ {
$plugin = $RCMAIL->plugins->exec_hook('contact_update', $plugin = $RCMAIL->plugins->exec_hook('contact_update',
array('id' => $cid, 'record' => $a_record, 'source' => get_input_value('_source', RCUBE_INPUT_GPC))); array('id' => $cid, 'record' => $a_record, 'source' => get_input_value('_source', RCUBE_INPUT_GPC)));
$a_record = $plugin['record']; $a_record = $plugin['record'];
if (!$plugin['abort']) if (!$plugin['abort'])
$result = $CONTACTS->update($cid, $a_record); $result = $CONTACTS->update($cid, $a_record);
else else
@ -70,7 +75,7 @@ if (!empty($cid))
// change cid in POST for 'show' action // change cid in POST for 'show' action
$_POST['_cid'] = $newcid; $_POST['_cid'] = $newcid;
} }
// define list of cols to be displayed // define list of cols to be displayed
$a_js_cols = array(); $a_js_cols = array();
$record = $CONTACTS->get_record($newcid ? $newcid : $cid, true); $record = $CONTACTS->get_record($newcid ? $newcid : $cid, true);
@ -80,7 +85,7 @@ if (!empty($cid))
// update the changed col in list // update the changed col in list
$OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid); $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid);
// show confirmation // show confirmation
$OUTPUT->show_message('successfullysaved', 'confirmation', null, false); $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
rcmail_overwrite_action('show'); rcmail_overwrite_action('show');

@ -29,13 +29,23 @@ $CONTACTS = $RCMAIL->get_address_book(null, true);
if (!empty($_POST['_address']) && is_object($CONTACTS)) if (!empty($_POST['_address']) && is_object($CONTACTS))
{ {
$contact_arr = $IMAP->decode_address_list(get_input_value('_address', RCUBE_INPUT_POST, true), 1, false); $contact_arr = $IMAP->decode_address_list(get_input_value('_address', RCUBE_INPUT_POST, true), 1, false);
if (!empty($contact_arr[1]['mailto'])) { if (!empty($contact_arr[1]['mailto'])) {
$contact = array( $contact = array(
'email' => $contact_arr[1]['mailto'], 'email' => $contact_arr[1]['mailto'],
'name' => $contact_arr[1]['name'] 'name' => $contact_arr[1]['name']
); );
// Validity checks
if (empty($contact['email'])) {
$OUTPUT->show_message('errorsavingcontact', 'error');
$OUTPUT->send();
}
else if (!check_email($contact['email'], false)) {
$OUTPUT->show_message('emailformaterror', 'error', array('email' => $contact['email']));
$OUTPUT->send();
}
$contact['email'] = idn_to_utf8($contact['email']); $contact['email'] = idn_to_utf8($contact['email']);
// use email address part for name // use email address part for name
@ -60,7 +70,7 @@ if (!empty($_POST['_address']) && is_object($CONTACTS))
} }
if (!$done) if (!$done)
$OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsavingcontact', 'warning'); $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsavingcontact', 'error');
$OUTPUT->send(); $OUTPUT->send();

Loading…
Cancel
Save