10 Commits
3.0 ... 3.4

Author SHA1 Message Date
Boris Gulay
d65ad79709 Added support for new Elastic skin in v1.4. Thanx to Estudio Nexos.
Closes #33
2018-12-06 20:07:52 +03:00
Boris Gulay
43a9ed178e Made git another way 2018-12-06 19:55:02 +03:00
Boris Gulay
cc68ab1521 JS optimizations. 2018-11-10 18:32:44 +03:00
Boris Gulay
ea21509f2a Added initial script for SQLite. Thanx to Gergely Papp. Closes #29. 2018-10-12 17:32:58 +03:00
Boris Gulay
24a9584d6f Fixed typo in field name. Closes #25 (thanx Dariusz Bijoś) 2018-08-27 22:24:48 +03:00
Boris Gulay
bcea012af0 Finally works correct for SMTP too. Closes #24. 2018-07-16 20:30:48 +03:00
Boris Gulay
a437a107ba Drop NOT NULL for username column.
Someone please check MySQL script!
2018-07-16 18:55:12 +03:00
Boris Gulay
8b2798e412 Show account selection only for MAIL task.
Optimize JS scripts.
2018-03-17 23:03:42 +03:00
Boris Gulay
c28305509f Fix identity form.
Closes #22.
2018-03-17 22:10:00 +03:00
Boris Gulay
8a8bca1ae5 Make identity selection work with classic skin. 2018-03-17 17:47:32 +03:00
14 changed files with 263 additions and 117 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.swp *.swp
.idea

View File

@@ -16,3 +16,6 @@ This plugin allows users to switch between different accounts (including remote)
* Branch 3.X - for Roundcube v1.3 * Branch 3.X - for Roundcube v1.3
Please specify verion like "~2.0" in your composer.json file for ident_switch requirement. In this case you will stay inside compatible branch until you manually update ypur Roundcube installation. Please specify verion like "~2.0" in your composer.json file for ident_switch requirement. In this case you will stay inside compatible branch until you manually update ypur Roundcube installation.
### Switching SMTP ###
Plugin also switched SMTP credentials but only for server specified in general config. You should use %u and %p substitutions for user and password to make it work. This substitutions are replaced by username and password for selected IMAP account.

View File

@@ -11,8 +11,7 @@ CREATE TABLE IF NOT EXISTS ident_switch
int(10) UNSIGNED int(10) UNSIGNED
NOT NULL, NOT NULL,
username username
varchar(64) varchar(64),
NOT NULL,
password password
varchar(64), varchar(64),
host host

6
SQL/mysql/2018071600.sql Normal file
View File

@@ -0,0 +1,6 @@
ALTER TABLE
ident_switch
MODIFY
username
varchar(64)
NULL;

View File

@@ -13,8 +13,7 @@ CREATE TABLE ident_switch
REFERENCES identities(identity_id) ON DELETE CASCADE ON UPDATE CASCADE REFERENCES identities(identity_id) ON DELETE CASCADE ON UPDATE CASCADE
UNIQUE, UNIQUE,
username username
varchar(64) varchar(64),
NOT NULL,
password password
varchar(64), varchar(64),
host host

View File

@@ -0,0 +1,5 @@
ALTER TABLE
ident_switch
ALTER COLUMN
username
DROP NOT NULL;

38
SQL/sqlite.initial.sql Normal file
View File

@@ -0,0 +1,38 @@
CREATE TABLE ident_switch
(
id
serial
PRIMARY KEY,
user_id
integer
NOT NULL
REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE,
iid
integer
NOT NULL
REFERENCES identities(identity_id) ON DELETE CASCADE ON UPDATE CASCADE
UNIQUE,
username
varchar(64),
password
varchar(64),
host
varchar(64),
port
integer
CHECK(port > 0 AND port <= 65535),
delimiter
char(1),
label
varchar(32),
flags
integer
NOT NULL
DEFAULT(0),
UNIQUE (user_id, label)
);
CREATE INDEX IX_ident_switch_user_id
ON
ident_switch(user_id);
CREATE INDEX IX_ident_switch_iid on ident_switch(iid);

41
ident_switch-form.js Normal file
View File

@@ -0,0 +1,41 @@
/*
* This is part of identity_imap plugin
*/
$(function() {
$("INPUT[name='_ident_switch.form.enabled']").change();
$("SELECT[name='_ident_switch.form.secure']").change();
plugin_switchIdent_processPreconfig();
});
function plugin_switchIdent_processPreconfig() {
var disFld = $("INPUT[name='_ident_switch.form.readonly']");
disFld.parentsUntil("TABLE", "TR").hide();
var disVal = disFld.val();
if (disVal > 0) {
$("INPUT[name='_ident_switch.form.host']").prop("disabled", true);
$("SELECT[name='_ident_switch.form.secure']").prop("disabled", true);
$("INPUT[name='_ident_switch.form.port']").prop("disabled", true);
}
if (2 == disVal) {
$("INPUT[name='_ident_switch.form.username']").prop("disabled", true);
}
}
function plugin_switchIdent_enabled_onChange(e) {
var $enFld = $("INPUT[name='_ident_switch.form.enabled']");
$("INPUT[name!='_ident_switch.form.enabled'], SELECT", $enFld.parents("FIELDSET")).prop("disabled", !$enFld.is(":checked"));
plugin_switchIdent_processPreconfig();
}
function plugin_switchIdent_secure_onChange(e) {
var $secSel = $("SELECT[name='_ident_switch.form.secure']");
var $portFld = $("INPUT[name='_ident_switch.form.port']");
if ('SSL' === $secSel.val().toUpperCase())
$portFld.attr("placeholder", 993);
else
$portFld.attr("placeholder", 143);
}

1
ident_switch-form.min.js vendored Normal file
View File

@@ -0,0 +1 @@
$(function(){$("INPUT[name='_ident_switch.form.enabled']").change();$("SELECT[name='_ident_switch.form.secure']").change();plugin_switchIdent_processPreconfig()});function plugin_switchIdent_processPreconfig(){var a=$("INPUT[name='_ident_switch.form.readonly']");a.parentsUntil("TABLE","TR").hide();var b=a.val();if(b>0){$("INPUT[name='_ident_switch.form.host']").prop("disabled",true);$("SELECT[name='_ident_switch.form.secure']").prop("disabled",true);$("INPUT[name='_ident_switch.form.port']").prop("disabled",true)}if(2==b){$("INPUT[name='_ident_switch.form.username']").prop("disabled",true)}}function plugin_switchIdent_enabled_onChange(a){var b=$("INPUT[name='_ident_switch.form.enabled']");$("INPUT[name!='_ident_switch.form.enabled'], SELECT",b.parents("FIELDSET")).prop("disabled",!b.is(":checked"));plugin_switchIdent_processPreconfig()}function plugin_switchIdent_secure_onChange(c){var b=$("SELECT[name='_ident_switch.form.secure']");var a=$("INPUT[name='_ident_switch.form.port']");if("SSL"===b.val().toUpperCase()){a.attr("placeholder",993)}else{a.attr("placeholder",143)}};

71
ident_switch-switch.js Normal file
View File

@@ -0,0 +1,71 @@
/*
* This is part of identity_imap plugin
*/
$(function() {
$sw = $('#plugin-ident_switch-account');
isOk = false;
switch (rcmail.env['skin']) {
case 'larry':
isOk = plugin_switchIdent_addCbLarry($sw);
break;
case 'classic':
isOk = plugin_switchIdent_addCbClassic($sw);
break;
case 'elastic':
isOk = plugin_switchIdent_addCbElastic($sw);
break;
}
if (isOk)
$sw.show();
});
function plugin_switchIdent_addCbLarry($sw) {
var $truName = $('.topright .username');
if ($truName.length > 0) {
if ($sw.length > 0) {
$sw.prependTo('.topright');
$truName.hide();
return true;
}
}
return false;
}
function plugin_switchIdent_addCbClassic($sw) {
var $taskBar = $('#taskbar');
if ($taskBar.length > 0) {
$taskBar.prepend($sw);
return true;
}
return false;
}
function plugin_switchIdent_addCbElastic($sw) {
var $taskBar = $('.header-title.username');
$sw.css("background-color", "transparent").css("border","none");
$sw.css("background-position-x","left 0.75rem").css("padding","0 0 0 2rem");
$sw.css("font-weight","bold").css("box-shadow","none");
if ($taskBar.length > 0) {
$taskBar.prepend($sw);
return true;
}
return false;
}
function plugin_switchIdent_switch(val) {
rcmail.env.unread_counts = {};
console.log(rcmail.env.unread_counts);
rcmail.http_post('plugin.ident_switch.switch', { '_ident-id': val, '_mbox': rcmail.env.mailbox });
}
function plugin_switchIdent_fixIdent(iid) {
if (parseInt(iid) > 0)
$("#_from").val(iid);
}

1
ident_switch-switch.min.js vendored Normal file
View File

@@ -0,0 +1 @@
$(function(){$sw=$("#plugin-ident_switch-account");isOk=false;switch(rcmail.env.skin){case"larry":isOk=plugin_switchIdent_addCbLarry($sw);break;case"classic":isOk=plugin_switchIdent_addCbClassic($sw);break;case"elastic":isOk=plugin_switchIdent_addCbElastic($sw);break}if(isOk){$sw.show()}});function plugin_switchIdent_addCbLarry(b){var a=$(".topright .username");if(a.length>0){if(b.length>0){b.prependTo(".topright");a.hide();return true}}return false}function plugin_switchIdent_addCbClassic(b){var a=$("#taskbar");if(a.length>0){a.prepend(b);return true}return false}function plugin_switchIdent_addCbElastic(b){var a=$(".header-title.username");b.css("background-color","transparent").css("border","none");b.css("background-position-x","left 0.75rem").css("padding","0 0 0 2rem");b.css("font-weight","bold").css("box-shadow","none");if(a.length>0){a.prepend(b);return true}return false}function plugin_switchIdent_switch(a){rcmail.env.unread_counts={};console.log(rcmail.env.unread_counts);rcmail.http_post("plugin.ident_switch.switch",{"_ident-id":a,_mbox:rcmail.env.mailbox})}function plugin_switchIdent_fixIdent(a){if(parseInt(a)>0){$("#_from").val(a)}};

View File

@@ -1,61 +0,0 @@
/*
* This is part of identity_imap plugin
*/
$(function() {
var $truName = $('.topright .username');
if ($truName.length > 0) {
$sw = $('#plugin-ident_switch-account');
if ($sw.length > 0) {
$sw.prependTo('.topright');
$truName.hide();
$('#plugin-ident_switch-account').show();
}
}
$("INPUT[name='_ident_switch.form.enabled']").change();
$("SELECT[name='_ident_switch.form.secure']").change();
plugin_switchIdent_processPreconfig();
});
function plugin_switchIdent_processPreconfig() {
var disFld = $("INPUT[name='_ident_switch.form.readonly']");
disFld.parentsUntil("TABLE", "TR").hide();
var disVal = disFld.val();
if (disVal > 0) {
$("INPUT[name='_ident_switch.form.host']").prop("disabled", true);
$("SELECT[name='_ident_switch.form.secure']").prop("disabled", true);
$("INPUT[name='_ident_switch.form.port']").prop("disabled", true);
}
if (2 == disVal) {
$("INPUT[name='_ident_switch.form.username']").prop("disabled", true);
}
}
function plugin_switchIdent_enabled_onChange(e) {
var $enFld = $("INPUT[name='_ident_switch.form.enabled']");
$("INPUT[name!='_ident_switch.form.enabled'], SELECT", $enFld.parents("FIELDSET")).prop("disabled", !$enFld.is(":checked"));
plugin_switchIdent_processPreconfig();
}
function plugin_switchIdent_secure_onChange(e) {
var $secSel = $("SELECT[name='_ident_switch.form.secure']");
var $portFld = $("INPUT[name='_ident_switch.form.port']");
if ('SSL' === $secSel.val().toUpperCase())
$portFld.attr("placeholder", 993);
else
$portFld.attr("placeholder", 143);
}
function plugin_switchIdent_switch(val) {
rcmail.http_post('plugin.ident_switch.switch', { '_ident-id': val, '_mbox': rcmail.env.mailbox });
}
function plugin_switchIdent_fixIdent(iid) {
if (parseInt(iid) > 0)
$("#_from").val(iid);
}

10
ident_switch.min.js vendored
View File

@@ -1,10 +0,0 @@
$(function(){var $truName=$('.topright .username');if($truName.length>0){$sw=$('#plugin-ident_switch-account');if($sw.length>0){$sw.prependTo('.topright');$truName.hide();$('#plugin-ident_switch-account').show();}}
$("INPUT[name='_ident_switch.form.enabled']").change();$("SELECT[name='_ident_switch.form.secure']").change();plugin_switchIdent_processPreconfig();});function plugin_switchIdent_processPreconfig(){var disFld=$("INPUT[name='_ident_switch.form.readonly']");disFld.parentsUntil("TABLE","TR").hide();var disVal=disFld.val();if(disVal>0){$("INPUT[name='_ident_switch.form.host']").prop("disabled",true);$("SELECT[name='_ident_switch.form.secure']").prop("disabled",true);$("INPUT[name='_ident_switch.form.port']").prop("disabled",true);}
if(2==disVal){$("INPUT[name='_ident_switch.form.username']").prop("disabled",true);}}
function plugin_switchIdent_enabled_onChange(e){var $enFld=$("INPUT[name='_ident_switch.form.enabled']");$("INPUT[name!='_ident_switch.form.enabled'], SELECT",$enFld.parents("FIELDSET")).prop("disabled",!$enFld.is(":checked"));plugin_switchIdent_processPreconfig();}
function plugin_switchIdent_secure_onChange(e){var $secSel=$("SELECT[name='_ident_switch.form.secure']");var $portFld=$("INPUT[name='_ident_switch.form.port']");if('SSL'===$secSel.val().toUpperCase())
$portFld.attr("placeholder",993);else
$portFld.attr("placeholder",143);}
function plugin_switchIdent_switch(val){rcmail.http_post('plugin.ident_switch.switch',{'_ident-id':val,'_mbox':rcmail.env.mailbox});}
function plugin_switchIdent_fixIdent(iid){if(parseInt(iid)>0)
$("#_from").val(iid);}

View File

@@ -58,16 +58,31 @@ class ident_switch extends rcube_plugin
{ {
$rc = rcmail::get_instance(); $rc = rcmail::get_instance();
// Currently selected identity switch ($rc->task)
$iid = $_SESSION['iid' . self::MY_POSTFIX]; {
case 'mail':
$this->render_switch($rc, $args);
case 'settings':
$this->include_script('ident_switch-form.js');
break;
}
$iid_int = 0;
if (is_int($iid)) return $args;
$iid_int = $iid; }
elseif ($iid === '-1')
$iid_int = -1; private function render_switch($rc, $args)
elseif (ctype_digit($iid)) {
$iid_int = intval($iid); // Currently selected identity
$iid_s = $_SESSION['iid' . self::MY_POSTFIX];
$iid = 0;
if (is_int($iid_s))
$iid = $iid_s;
elseif ($iid_s === '-1')
$iid = -1;
elseif (ctype_digit($iid_s))
$iid = intval($iid_s);
// Get list of alternative accounts // Get list of alternative accounts
$sOpt = ''; $sOpt = '';
@@ -76,7 +91,7 @@ class ident_switch extends rcube_plugin
while ($r = $rc->db->fetch_assoc($qRec)) while ($r = $rc->db->fetch_assoc($qRec))
{ {
$opts = array('value' => $r['id']); $opts = array('value' => $r['id']);
if ($iid_int == $r['iid']) if ($iid == $r['iid'])
$opts['selected'] = 'selected'; $opts['selected'] = 'selected';
// Make label // Make label
@@ -110,7 +125,7 @@ class ident_switch extends rcube_plugin
{ {
// Add main account // Add main account
$opts = array('value' => -1); $opts = array('value' => -1);
if (!$iid || $iid_int == -1) if ($iid <= 0)
$opts['selected'] = 'selected'; $opts['selected'] = 'selected';
$sOpt = html::tag( $sOpt = html::tag(
@@ -119,7 +134,7 @@ class ident_switch extends rcube_plugin
$_SESSION['global_alias'] ? $_SESSION['global_alias'] : $rc->user->data['username'] $_SESSION['global_alias'] ? $_SESSION['global_alias'] : $rc->user->data['username']
) . $sOpt; ) . $sOpt;
$this->include_script('ident_switch.js'); $this->include_script('ident_switch-switch.js');
$sw = html::tag( $sw = html::tag(
'select', 'select',
array( array(
@@ -131,22 +146,33 @@ class ident_switch extends rcube_plugin
); );
$rc->output->add_footer($sw); $rc->output->add_footer($sw);
} }
return $args;
} }
function on_smtp_connect($args) function on_smtp_connect($args)
{ {
$iid = $_SESSION['iid' . self::MY_POSTFIX];
if (!is_integer($iid) || $iid == -1)
return $args;
$rc = rcmail::get_instance(); $rc = rcmail::get_instance();
// TODO: Rewrite with full settings! $sql = 'SELECT host, flags, port, username, password, iid FROM ' . $rc->db->table_name(self::TABLE) . ' WHERE iid = ? AND user_id = ?';
$q = $rc->db->query($sql, $iid ,$rc->user->ID);
if (strcasecmp($rc->user->data['username'], $_SESSION['username']) !== 0) $r = $rc->db->fetch_assoc($q);
if (is_array($r))
{ {
if ($args['smtp_user'] == '%u') if (!$r['username'])
$args['smtp_user'] = $rc->user->data['username']; { // Load email from identity
if ($args['smtp_pass'] == '%p') $sql = 'SELECT email FROM ' . $rc->db->table_name('identities') . ' WHERE identity_id = ?';
$args['smtp_pass'] = $rc->decrypt($_SESSION['password' . self::MY_POSTFIX]); $q = $rc->db->query($sql, $r['iid']);
$rIid = $rc->db->fetch_assoc($q);
$r['username'] = $rIid['email'];
}
// Exactly the same in core SMTP handler
$args['smtp_user'] = str_replace('%u', $r['username'], $args['smtp_user']);
$args['smtp_pass'] = str_replace('%p', $rc->decrypt($r['password']), $args['smtp_pass']);
} }
return $args; return $args;
@@ -162,26 +188,6 @@ class ident_switch extends rcube_plugin
$this->add_texts('localization'); $this->add_texts('localization');
// Create our field set
$args['form']['ident_switch'] = array(
'name' => $this->gettext('form.caption'),
'content' => array(
'ident_switch.form.enabled' => array('type' => 'checkbox', 'onchange' => 'plugin_switchIdent_enabled_onChange();'),
'ident_switch.form.label' => array('type' => 'text', 'size' => 32, 'placeholder' => $args['record']['email']),
'ident_switch.form.host' => array('type' => 'text', 'size' => 64, 'placeholder' => 'localhost'),
'ident_switch.form.secure' => array(
'type' => 'select',
'options' => array('ssl' => 'SSL', 'tls' => 'TLS'),
'onchange' => 'plugin_switchIdent_secure_onChange();'
),
'ident_switch.form.port' => array('type' => 'text', 'size' => 5),
'ident_switch.form.username' => array('type' => 'text', 'size' => 64, 'placeholder' => $args['record']['email']),
'ident_switch.form.password' => array('type' => 'password', 'size' => 64),
'ident_switch.form.delimiter' => array('type' => 'text', 'size' => 1, 'placeholder' => '.'),
'ident_switch.form.readonly' => array('type' => 'hidden'),
),
);
// Load data if exists // Load data if exists
if (isset($args['record']['identity_id'])) if (isset($args['record']['identity_id']))
{ {
@@ -214,6 +220,52 @@ class ident_switch extends rcube_plugin
$this->apply_preconfig($args['record']); $this->apply_preconfig($args['record']);
} }
// Create our field set
// Do that manually decause standard processing shows hidden fields (WTF?)
$fieldset = array(
'ident_switch.form.enabled' => array('type' => 'checkbox', 'onchange' => 'plugin_switchIdent_enabled_onChange();'),
'ident_switch.form.label' => array('type' => 'text', 'size' => 32, 'placeholder' => $args['record']['email']),
'ident_switch.form.host' => array('type' => 'text', 'size' => 64, 'placeholder' => 'localhost'),
'ident_switch.form.secure' => array(
'type' => 'select',
'options' => array('ssl' => 'SSL', 'tls' => 'TLS'),
'onchange' => 'plugin_switchIdent_secure_onChange();'
),
'ident_switch.form.port' => array('type' => 'text', 'size' => 5),
'ident_switch.form.username' => array('type' => 'text', 'size' => 64, 'placeholder' => $args['record']['email']),
'ident_switch.form.password' => array('type' => 'password', 'size' => 64),
'ident_switch.form.delimiter' => array('type' => 'text', 'size' => 1, 'placeholder' => '.'),
'ident_switch.form.readonly' => array('type' => 'hidden'),
);
// Process fields
$addAfter = '';
$table = new html_table(array('cols' => 2));
foreach ($fieldset as $col => $colprop)
{
$data = $args['record'][$col];
if ($colprop['type'] == 'hidden')
{
$addAfter .= rcube_output::get_edit_field($col, $data, $colprop, $colprop['type']);
}
else
{
$colprop['id'] = 'rcmfd_' . $col;
$label = $colprop['label'] ?: $this->gettext(str_replace('-', '', $col));
$value = $colprop['value'] ?: rcube_output::get_edit_field($col, $data, $colprop, $colprop['type']);
$table->add('title', html::label($colprop['id'], rcube::Q($label)));
$table->add(null, $value);
}
}
// Set data for output
$args['form']['ident_switch'] = array(
'name' => $this->gettext('form.caption'),
'content' => $table->show(array('class' => 'propform')) . $addAfter // TODO: copy styles from other tables
);
return $args; return $args;
} }
@@ -228,7 +280,7 @@ class ident_switch extends rcube_plugin
// Process boolean fields // Process boolean fields
if (!rcube_utils::get_input_value('_ident_switch_form_enabled', rcube_utils::INPUT_POST)) if (!rcube_utils::get_input_value('_ident_switch_form_enabled', rcube_utils::INPUT_POST))
{ {
self::sw_imap_off($args['iid']); self::sw_imap_off($args['id']);
return $args; return $args;
} }