Warn about too many disclosed recipients in composed email [max_disclosed_recipients] (#5132)

Allow to omit a subject when sending an email (#5068)
pull/5507/head
Aleksander Machniak 8 years ago
parent 059dc8b635
commit 2dbbaf7739

@ -1,6 +1,8 @@
CHANGELOG Roundcube Webmail
===========================
- Allow to omit a subject when sending an email (#5068)
- Warn about too many disclosed recipients in composed email [max_disclosed_recipients] (#5132)
- identity_select: Support Received header (#5085)
- Plugin API: Added get_compose_responses hook (#5457)
- Display error when trying to upload more files than specified in max_file_uploads (#5483)

@ -521,9 +521,15 @@ $config['sendmail_delay'] = 0;
// Size in bytes (possible unit suffix: K, M, G)
$config['max_message_size'] = '100M';
// Maximum number of recipients per message. Default: 0 (no limit)
// Maximum number of recipients per message (including To, Cc, Bcc).
// Default: 0 (no limit)
$config['max_recipients'] = 0;
// Maximum number of recipients per message exluding Bcc header.
// This is a soft limit, which means we only display a warning to the user.
// Default: 5
$config['max_disclosed_recipients'] = 5;
// Maximum allowed number of members of an address group. Default: 0 (no limit)
// If 'max_recipients' is set this value should be less or equal
$config['max_group_members'] = 0;

@ -4345,14 +4345,23 @@ function rcube_webmail()
};
// checks the input fields before sending a message
this.check_compose_input = function(cmd)
this.check_compose_input = function(cmd, skip_recipients_checks)
{
// check input fields
var input_to = $("[name='_to']"),
var key, recipients, dialog,
limit = this.env.max_disclosed_recipients,
input_to = $("[name='_to']"),
input_cc = $("[name='_cc']"),
input_bcc = $("[name='_bcc']"),
input_from = $("[name='_from']"),
input_subject = $("[name='_subject']");
input_subject = $("[name='_subject']"),
get_recipients = function(fields) {
fields = $.map(fields, function(v) {
v = $.trim(v.val());
return v.length ? v : null;
});
return fields.join(',').replace(/^[\s,;]+/, '').replace(/[\s,;]+$/, '');
};
// check sender (if have no identities)
if (input_from.prop('type') == 'text' && !rcube_check_email(input_from.val(), true)) {
@ -4362,53 +4371,92 @@ function rcube_webmail()
}
// check for empty recipient
var recipients = input_to.val() ? input_to.val() : (input_cc.val() ? input_cc.val() : input_bcc.val());
if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true)) {
recipients = get_recipients([input_to, input_cc, input_bcc]);
if (!skip_recipients_checks && !rcube_check_email(recipients, true)) {
alert(this.get_label('norecipientwarning'));
input_to.focus();
return false;
}
// check if all files has been uploaded
for (var key in this.env.attachments) {
for (key in this.env.attachments) {
if (typeof this.env.attachments[key] === 'object' && !this.env.attachments[key].complete) {
alert(this.get_label('notuploadedwarning'));
return false;
}
}
// check disclosed recipients limit
if (limit && !skip_recipients_checks && !this.env.disclosed_recipients_warned
&& rcube_check_email(recipients = get_recipients([input_to, input_cc]), true, true) > limit
) {
var save_func = function(move_to_bcc) {
if (move_to_bcc) {
var bcc = input_bcc.val();
input_bcc.val((bcc ? (bcc + ', ') : '') + recipients).change();
input_to.val('').change();
input_cc.val('').change();
}
dialog.dialog('close');
ref.check_compose_input(cmd, true);
};
dialog = this.show_popup_dialog(
this.get_label('disclosedrecipwarning'),
this.get_label('disclosedreciptitle'),
[{
text: this.get_label('sendmessage'),
click: function() { save_func(false); },
'class': 'mainaction'
}, {
text: this.get_label('bccinstead'),
click: function() { save_func(true); }
}, {
text: this.get_label('cancel'),
click: function() { dialog.dialog('close'); }
}],
{dialogClass: 'warning'}
);
this.env.disclosed_recipients_warned = true;
return false;
}
// display localized warning for missing subject
if (input_subject.val() == '') {
var buttons = {},
myprompt = $('<div class="prompt">').html('<div class="message">' + this.get_label('nosubjectwarning') + '</div>')
.appendTo(document.body),
prompt_value = $('<input>').attr({type: 'text', size: 30}).val(this.get_label('nosubject'))
.appendTo(myprompt),
if (!this.env.nosubject_warned && input_subject.val() == '') {
var prompt_value = $('<input>').attr({type: 'text', size: 40}),
myprompt = $('<div class="prompt">')
.append($('<div class="message">').text(this.get_label('nosubjectwarning')))
.append(prompt_value),
save_func = function() {
input_subject.val(prompt_value.val());
myprompt.dialog('close');
dialog.dialog('close');
ref.command(cmd, { nocheck:true }); // repeat command which triggered this
};
buttons[this.get_label('sendmessage')] = function() {
save_func($(this));
};
buttons[this.get_label('cancel')] = function() {
input_subject.focus();
$(this).dialog('close');
};
myprompt.dialog({
modal: true,
resizable: false,
buttons: buttons,
close: function(event, ui) { $(this).remove(); }
});
dialog = this.show_popup_dialog(
myprompt,
this.get_label('nosubjecttitle'),
[{
text: this.get_label('sendmessage'),
click: function() { save_func(); },
'class': 'mainaction'
}, {
text: this.get_label('cancel'),
click: function() {
input_subject.focus();
dialog.dialog('close');
}
}],
{dialogClass: 'warning'}
);
prompt_value.select().keydown(function(e) {
if (e.which == 13) save_func();
});
this.env.nosubject_warned = true;
return false;
}

@ -407,10 +407,14 @@ triggerEvent: function(evt, e)
// check if input is a valid email address
// By Cal Henderson <cal@iamcal.com>
// http://code.iamcal.com/php/rfc822/
function rcube_check_email(input, inline)
function rcube_check_email(input, inline, count)
{
if (input && window.RegExp) {
var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]',
if (!input)
return count ? 0 : false;
if (count) inline = true;
var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]',
dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]',
atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+',
quoted_pair = '\\x5c[\\x00-\\x7f]',
@ -443,12 +447,13 @@ function rcube_check_email(input, inline)
delim = '[,;\\s\\n]',
local_part = word+'(\\x2e'+word+')*',
addr_spec = '(('+local_part+'\\x40'+domain+')|('+icann_addr+'))',
reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
rx_flag = count ? 'ig' : 'i',
rx = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', rx_flag) : new RegExp('^'+addr_spec+'$', 'i');
return reg1.test(input) ? true : false;
}
if (count)
return input.match(rx).length;
return false;
return rx.test(input);
};
// recursively copy an object

@ -266,6 +266,7 @@ $labels['keyid'] = 'Key ID';
$labels['keylength'] = 'Bits';
$labels['keyexpired'] = 'Expired';
$labels['keyrevoked'] = 'Revoked';
$labels['bccinstead'] = 'Use Bcc';
$labels['editidents'] = 'Edit identities';
$labels['spellcheck'] = 'Spell';

@ -94,7 +94,10 @@ $messages['nonamewarning'] = 'Please enter a name.';
$messages['nopagesizewarning'] = 'Please enter a page size.';
$messages['nosenderwarning'] = 'Please enter sender email address.';
$messages['norecipientwarning'] = 'Please enter at least one recipient.';
$messages['disclosedrecipwarning'] = 'All recipients will see each others e-mail addresses. To prevent this and protect their privacy you can use the Bcc field.';
$messages['disclosedreciptitle'] = 'Too many public recipients';
$messages['nosubjectwarning'] = 'The "Subject" field is empty. Would you like to enter one now?';
$messages['nosubjecttitle'] = 'No subject';
$messages['nobodywarning'] = 'Send this message without text?';
$messages['notsentwarning'] = 'Message has not been sent. Do you want to discard your message?';
$messages['restoresavedcomposedata'] = 'A previously composed but unsent message was found.\n\nSubject: $subject\nSaved: $date\n\nDo you want to restore this message?';

@ -88,7 +88,8 @@ $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubj
'selectimportfile', 'messageissent', 'loadingdata', 'nopubkeyfor', 'nopubkeyforsender',
'encryptnoattachments','encryptedsendialog','searchpubkeyservers', 'importpubkeys',
'encryptpubkeysfound', 'search', 'close', 'import', 'keyid', 'keylength', 'keyexpired',
'keyrevoked', 'keyimportsuccess', 'keyservererror', 'attaching', 'namex', 'attachmentrename');
'keyrevoked', 'keyimportsuccess', 'keyservererror', 'attaching', 'namex', 'attachmentrename',
'disclosedrecipwarning', 'disclosedreciptitle', 'bccinstead', 'nosubjecttitle');
$OUTPUT->set_pagetitle($RCMAIL->gettext('compose'));
@ -99,6 +100,7 @@ $OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0);
$OUTPUT->set_env('sig_below', $RCMAIL->config->get('sig_below'));
$OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ',')));
$OUTPUT->set_env('save_localstorage', (bool)$RCMAIL->config->get('compose_save_localstorage'));
$OUTPUT->set_env('max_disclosed_recipients', (int) $RCMAIL->config->get('max_disclosed_recipients', 5));
$OUTPUT->set_env('is_sent', false);
$OUTPUT->set_env('mimetypes', rcmail_supported_mimetypes());

@ -44,9 +44,7 @@ if (!isset($COMPOSE['id'])) {
}
if (!$savedraft) {
if (empty($_POST['_to']) && empty($_POST['_cc']) && empty($_POST['_bcc'])
&& empty($_POST['_subject']) && $_POST['_message']
) {
if (empty($_POST['_to']) && empty($_POST['_cc']) && empty($_POST['_bcc']) && $_POST['_message']) {
$OUTPUT->show_message('sendingfailed', 'error');
$OUTPUT->send('iframe');
}
@ -171,10 +169,11 @@ if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) {
$dont_override = (array) $RCMAIL->config->get('dont_override');
$mdn_enabled = in_array('mdn_default', $dont_override) ? $RCMAIL->config->get('mdn_default') : !empty($_POST['_mdn']);
$dsn_enabled = in_array('dsn_default', $dont_override) ? $RCMAIL->config->get('dsn_default') : !empty($_POST['_dsn']);
$subject = trim(rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, TRUE, $message_charset));
// add subject
$headers['Subject'] = trim(rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, TRUE, $message_charset));
if (strlen($subject)) {
$headers['Subject'] = $subject;
}
if (!empty($identity_arr['organization'])) {
$headers['Organization'] = $identity_arr['organization'];
}

Loading…
Cancel
Save