21 Commits
0.6 ... 0.8

Author SHA1 Message Date
Boris Gulay
d667518d1f Fixed vary dangerous error when while editing settings ALL records ware
updated instead of only one.
2016-05-28 00:29:35 +03:00
Boris Gulay
5ad75ce989 Field validation code refactored. 2016-05-28 00:22:57 +03:00
Boris Gulay
dbadde3333 Fixed validation error when editing identity with Enabled not checked. 2016-05-28 00:22:57 +03:00
Boris Gulay
b499688318 Fixed #2 validation error when saving default identity (thanx Wouter de
Geus).
2016-05-28 00:22:49 +03:00
Boris Gulay
6cfbeab7f0 Added RUS messages for validation errors. 2016-05-27 23:42:46 +03:00
Boris Gulay
b10f3625c2 Added string in ENG for all validation erros. 2016-05-27 23:25:26 +03:00
Boris Gulay
f28fb5bb58 Added initial script for MySQL (thanx Wouter de Geus). Closes #1. 2016-05-27 22:46:58 +03:00
Boris Gulay
1b424b4348 Fixed check for port number (cannot be 0). 2016-05-21 01:22:41 +03:00
Boris Gulay
6705312240 Removed NOT NULL constraints in initial file. 2016-05-21 01:22:41 +03:00
Boris Gulay
05ea494fa6 README.md edited online with Bitbucket 2016-05-20 20:42:22 +00:00
Boris Gulay
5a704f2717 Fixed double encryption of pwd when changing record (cannot connect
after change).
2016-05-20 23:40:48 +03:00
Boris Gulay
01edffa66b Removed unused skin-related styles. 2016-05-20 23:21:15 +03:00
Boris Gulay
9367409f36 Russian translation added. 2016-05-20 23:21:15 +03:00
Boris Gulay
bbf28eed57 Label and host are not required from now. 2016-05-20 23:21:15 +03:00
Boris Gulay
ec71910156 Done better checks and saving NULL instead of empty string. 2016-05-20 23:21:15 +03:00
Boris Gulay
f700593730 Added data validation for identity form. 2016-05-20 23:21:15 +03:00
Boris Gulay
9db4f48593 Do now show connection options for default identity. 2016-05-20 23:21:15 +03:00
Boris Gulay
2b9c43858e Fixed bug when account selected is shown twice on settings pages. 2016-05-20 23:21:15 +03:00
Boris Gulay
95716183d7 Make fields on form disabled if Enabled not checked. 2016-05-20 23:21:15 +03:00
Boris Gulay
40e7f5664e Missing string added. 2016-05-20 23:21:15 +03:00
Boris Gulay
ea62869891 README.md edited online with Bitbucket 2016-05-20 16:06:32 +00:00
11 changed files with 292 additions and 89 deletions

View File

@@ -4,3 +4,8 @@ ident_switch plugin for Roundcube
This plugin allows users to switch between different accounts (including remote) in single Roundcube session.
*Inspired by identities_imap plugin that is no longer supported.*
### Where to start ###
* In settigs interface create new identity.
* For all identities except default you will see new section of settings - IMAP. Enter data required to connect to remote server. Don't forget to check Enabled check box.
* After you have created at least one identity with active IMAP settings you will see combobox in the top right corner instead of plain text field with account name. It will allows you to switch to another account.

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

@@ -0,0 +1,38 @@
CREATE TABLE IF NOT EXISTS ident_switch
(
id
int(10) UNSIGNED
NOT NULL
AUTO_INCREMENT,
user_id
int(10) UNSIGNED
NOT NULL,
iid
int(10) UNSIGNED
NOT NULL,
username
varchar(64)
NOT NULL,
password
varchar(64),
host
varchar(64),
port
int
CHECK(port > 0 AND port <= 65535),
delimiter
char(1),
label
varchar(32),
flags
int
NOT NULL
DEFAULT 0,
UNIQUE KEY user_id_label (user_id, label),
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_identity_id FOREIGN KEY (iid) REFERENCES identities(identity_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(id),
INDEX IX_ident_switch_user_id (user_id),
INDEX IX_ident_switch_iid (iid)
);

View File

@@ -18,16 +18,14 @@ CREATE TABLE ident_switch
password
varchar(64),
host
varchar(64)
NOT NULL,
varchar(64),
port
integer
CHECK(port > 0 AND port <= 65535),
delimiter
char(1),
label
varchar(32)
NOT NULL,
varchar(32),
flags
integer
NOT NULL

View File

@@ -0,0 +1,11 @@
ALTER TABLE
ident_switch
ALTER COLUMN
host
DROP NOT NULL;
ALTER TABLE
ident_switch
ALTER COLUMN
label
DROP NOT NULL;

View File

@@ -1,14 +1,29 @@
/*
* This is part of identity_imap plugin
*/
$(function() {
if ($('#plugin-ident_switch-account').size() > 0) {
$('#plugin-ident_switch-account').prependTo('.topright');
$('.topright .username').hide();
var $truName = $('.topright .username');
if ($truName.size() > 0) {
$sw = $('#plugin-ident_switch-account');
if ($sw.size() > 0) {
$sw.prependTo('.topright');
$truName.hide();
$('#plugin-ident_switch-account').show();
console.log("Doing replace.");
}
}
var $enFld = $("INPUT[name='_ident_switch.form.enabled']");
if ($enFld.size() == 1)
$enFld.change();
});
function plugin_switchIdent_enabled_onChange(e) {
var $enFld = $("INPUT[name='_ident_switch.form.enabled']");
$("INPUT[name!='_ident_switch.form.enabled']", $enFld.parents("FIELDSET")).prop("disabled", !$enFld.is(":checked"));
}
function plugin_switchIdent_switch(val) {
console.log("qwe1");
rcmail.http_post('plugin.ident_switch.switch', { '_ident-id': val });

View File

@@ -67,17 +67,26 @@ class ident_switch extends rcube_plugin
if (strcasecmp($_SESSION['username'], $r['username']) === 0)
$opts['selected'] = 'selected';
// Make label
$lbl = $r['label'];
if (!$lbl)
{
if (strpos($r['username'], '@') === false)
$lbl = $r['username'] . '@' . ($r['host'] ? $r['host'] : 'localhost');
else
$lbl = $r['username'];
}
$sOpt .= html::tag(
'option',
$opts,
$r['label']
rcube::Q($lbl)
);
}
// Render UI if user has extra accounts
if (!empty($sOpt))
{
// Add main account
$opts = array('value' => -1);
if (strcasecmp($_SESSION['username'], $rc->user->data['username']) === 0)
@@ -125,13 +134,18 @@ class ident_switch extends rcube_plugin
function on_identity_form($args)
{
$rc = rcmail::get_instance();
// Do not show options for default identity
if (strcasecmp($args['record']['email'], $rc->user->data['username']) === 0)
return $args;
$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'),
'ident_switch.form.enabled' => array('type' => 'checkbox', 'onchange' => 'plugin_switchIdent_enabled_onChange();'),
'ident_switch.form.label' => array('type' => 'text', 'size' => 32),
'ident_switch.form.host' => array('type' => 'text', 'size' => 64),
'ident_switch.form.secure' => array('type' => 'checkbox'),
@@ -168,23 +182,9 @@ class ident_switch extends rcube_plugin
{
$rc = rcmail::get_instance();
// TODO: check field values
$sql = 'SELECT NULL FROM ' . $rc->db->table_name($this->table) . ' WHERE iid = ? AND user_id = ?';
$q = $rc->db->query($sql, $args['id'], $rc->user->ID);
$r = $rc->db->fetch_assoc($q);
if ($r)
{ // Record already exists, will update it
$sql = 'UPDATE ' .
$rc->db->table_name($this->table) .
' SET flags = ?, label = ?, host = ?, port = ?, username = ?, password = ?, delimiter = ?, user_id = ?, iid = ?';
}
else
{ // No record exists, create new one
$sql = 'INSERT INTO ' .
$rc->db->table_name($this->table) .
'(flags, label, host, port, username, password, delimiter, user_id, iid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)';
}
// Do not do anything for default identity
if (strcasecmp($args['record']['email'], $rc->user->data['username']) === 0)
return $args;
// Process boolean fields
$flags = 0;
@@ -193,18 +193,99 @@ class ident_switch extends rcube_plugin
if (get_input_value('_ident_switch_form_secure', RCUBE_INPUT_POST))
$flags |= $this->db_secure;
if (!($flags & $this->db_enabled))
{
$this->sw_imap_off($args['iid']);
return $args;
}
// Check field values
$errMsg = '';
$fLabel = self::ntrim(get_input_value('_ident_switch_form_label', RCUBE_INPUT_POST));
if (strlen($fLabel) > 32)
$errMsg = 'label.long';
else
{
$fHost = self::ntrim(get_input_value('_ident_switch_form_host', RCUBE_INPUT_POST));
if (strlen($fHost) > 64)
$errMsg = 'host.long';
else
{
$fPort = self::ntrim(get_input_value('_ident_switch_form_port', RCUBE_INPUT_POST));
if ($fPort && !ctype_digit($fPort))
$errMsg = 'port.num';
else
{
if ($fPort && ($fPort <= 0 || $fPort > 65535))
$errMsg = 'port.range';
else
{
$fUser = self::ntrim(get_input_value('_ident_switch_form_username', RCUBE_INPUT_POST));
if (strlen($fUser) > 64)
$errMsg = 'user.long';
else
{
if (!$fUser)
$errMsg = 'user.empty';
else
{
$fDelim = self::ntrim(get_input_value('_ident_switch_form_delimiter', RCUBE_INPUT_POST));
if (strlen($fDelim) > 1)
$errMsg = 'delim.long';
}
}
}
}
}
}
if ($errMsg)
{
$this->add_texts('localization');
$rc->output->show_message('ident_switch.err.' . $errMsg, 'error');
$args['abort'] = true;
return $args;
}
$sql = 'SELECT id, password FROM ' . $rc->db->table_name($this->table) . ' WHERE iid = ? AND user_id = ?';
$q = $rc->db->query($sql, $args['id'], $rc->user->ID);
$r = $rc->db->fetch_assoc($q);
if ($r)
{ // Record already exists, will update it
$sql = 'UPDATE ' .
$rc->db->table_name($this->table) .
' SET flags = ?, label = ?, host = ?, port = ?, username = ?, password = ?, delimiter = ?, user_id = ?, iid = ?' .
' WHERE id = ?';
}
else if ($flags & $this->db_enabled)
{ // No record exists, create new one
$sql = 'INSERT INTO ' .
$rc->db->table_name($this->table) .
'(flags, label, host, port, username, password, delimiter, user_id, iid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)';
}
if ($sql)
{
// Do we need to update pwd?
$fPass = get_input_value('_ident_switch_form_password', RCUBE_INPUT_POST);
if ($fPass != $r['password'])
$fPass = $rc->encrypt($fPass);
$rc->db->query(
$sql,
$flags,
get_input_value('_ident_switch_form_label', RCUBE_INPUT_POST),
get_input_value('_ident_switch_form_host', RCUBE_INPUT_POST),
get_input_value('_ident_switch_form_port', RCUBE_INPUT_POST),
get_input_value('_ident_switch_form_username', RCUBE_INPUT_POST),
$rc->encrypt(get_input_value('_ident_switch_form_password', RCUBE_INPUT_POST)),
get_input_value('_ident_switch_form_delimiter', RCUBE_INPUT_POST),
$fLabel,
$fHost,
$fPort,
$fUser,
$fPass,
$fDelim,
$rc->user->ID,
$args['id']
$args['id'],
$r['id']
);
}
return $args;
}
@@ -298,7 +379,7 @@ class ident_switch extends rcube_plugin
}
$_SESSION['password' . $this->my_postfix] = $_SESSION['password'];
$_SESSION['storage_host'] = $r['host'];
$_SESSION['storage_host'] = $r['host'] ? $r['host'] : 'localhost'; // Default host here!
$_SESSION['storage_ssl'] = $ssl;
$_SESSION['storage_port'] = $port;
$_SESSION['username'] = $r['username'];
@@ -322,4 +403,24 @@ class ident_switch extends rcube_plugin
)
);
}
protected function sw_imap_off($iid)
{
$rc = rcmail::get_instance();
$sql = 'UPDATE ' . $rc->db->table_name($this->table) . ' SET flags = flags & ? WHERE iid = ? AND user_id = ?';
$rc->db->query($sql, ~$this->db_enabled, $iid, $rc->user->ID);
}
protected static function ntrim($str)
{
if (is_null($str))
return $str;
$s = trim($str);
if (!$s)
return null;
return $s;
}
}

View File

@@ -13,8 +13,14 @@ $labels['form.enabled'] = 'Enabled';
// Label
$labels['form.label'] = 'Label';
// Server URI
$labels['form.server']='Server URI';
// Server host name
$labels['form.host']='Server host name';
// Secure connection (SSL/TLS)
$labels['form.secure']='Secure connection (SSL/TLS)';
// Port
$labels['form.port']='Port';
// Username
$labels['form.username'] = 'Username';
@@ -24,3 +30,24 @@ $labels['form.password'] = 'Password';
// Folder hierarchy delimiter
$labels['form.delimiter'] = 'Folder hierarchy delimiter';
// \'Username\' field in IMAP section cannot be empty.
$labels['err.user.empty'] = '\'Username\' field in IMAP section cannot be empty.';
// Value in \'Label\' field of IMAP section is too long (32 chars max).
$labels['err.label.long'] = 'Value in \'Label\' field of IMAP section is too long (32 chars max).';
// Value in \'Server host name\' field of IMAP section is too long (64 chars max).
$labels['err.host.long'] = 'Value in \'Server host name\' field of IMAP section is too long (64 chars max).';
// Value in \'Username\' field of IMAP section is too long (64 chars max).
$labels['err.user.long'] = 'Value in \'Username\' field of IMAP section is too long (64 chars max).';
// Value in \'Folder hierarchy delimiter\' field of IMAP section is too long (1 char max).
$labels['err.delim.long'] = 'Value in \'Folder hierarchy delimiter\' field of IMAP section is too long (1 char max).';
// Value in \'Port\' field of IMAP section must be a number.
$labels['err.port.num'] = 'Value in \'Port\' field of IMAP section must be a number.';
// Value in \'Port\' field of IMAP section must be between 1 and 65535.
$labels['err.port.rtange'] = 'Value in \'Port\' field of IMAP section must be between 1 and 65535.';

53
localization/ru_RU.inc Normal file
View File

@@ -0,0 +1,53 @@
<?php
/*
* Localization file for ident_switch plugin
*/
$labels = array();
// IMAP
$labels['form.caption'] = 'IMAP';
// Enabled
$labels['form.enabled'] = 'Включено';
// Label
$labels['form.label'] = 'Название';
// Server host name
$labels['form.host'] = 'Адрес сервера';
// Secure connection (SSL/TLS)
$labels['form.secure'] = 'Безопасное соединение (SSL/TLS)';
// Port
$labels['form.port'] = 'Порт';
// Username
$labels['form.username'] = 'Имя пользователя';
// Passwotrd
$labels['form.password'] = 'Пароль';
// Folder hierarchy delimiter
$labels['form.delimiter'] = 'Разделитель в иерархии папок';
// \'Username\' field in IMAP section cannot be empty.
$labels['err.user.empty'] = '\'Имя пользователя\' в разделе IMAP не может быть пустым.';
// Value in \'Label\' field of IMAP section is too long (32 chars max).
$labels['err.label.long'] = '\'Название\' в разделе IMAP должно быть не длинее 32 символов.';
// Value in \'Server host name\' field of IMAP section is too long (64 chars max).
$labels['err.host.long'] = '\'Адрес сервера\' в разделе IMAP должен быть не длинее 64 символов.';
// Value in \'Username\' field of IMAP section is too long (64 chars max).
$labels['err.user.long'] = '\'Имя пользователя\' в секции IMAP должно быть не длинее 64 символов.';
// Value in \'Folder hierarchy delimiter\' field of IMAP section is too long (1 char max).
$labels['err.delim.long'] = '\'Разделитель в иерархии папок\' в секции IMAP должен быть не длинее 1 символа.';
// Value in \'Port\' field of IMAP section must be a number.
$labels['err.port.num'] = '\'Порт\' в секции IMAP должен быть числом.';
// Value in \'Port\' field of IMAP section must be between 1 and 65535.
$labels['err.port.rtange'] = '\'Порт\' в секции IMAP должен быть в диапазоне от 1 до 65535.';

View File

@@ -1,15 +0,0 @@
/***************************************************************************
* This file is part of Roundcube "identities_imap" plugin.
*
* Your are not allowed to distribute this file or parts of it.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Copyright (c) 2012 - 2014 Roland 'Rosali' Liebl - all rights reserved
* dev-team [at] myroundcube [dot] com
* http://myroundcube.com
***************************************************************************/
#accounts{position:absolute; top:63px; left:18px;}.remotehint{z-index:-1; position:absolute; top:7px; margin-left:auto; left:210px; width:400px; border-radius:5px; padding:4px; -moz-border-radius:5px; border:1px solid #DEEEFC; background:#F2F9FF; text-align:center; color:#3F70BA; display:inline;}.classic{top:2px;}

View File

@@ -1,15 +0,0 @@
/***************************************************************************
* This file is part of Roundcube "identities_imap" plugin.
*
* Your are not allowed to distribute this file or parts of it.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Copyright (c) 2012 - 2014 Roland 'Rosali' Liebl - all rights reserved
* dev-team [at] myroundcube [dot] com
* http://myroundcube.com
***************************************************************************/
select.deco{height:18px; font-size:12px; border-radius:3px; -moz-border-radius:3px; -webkit-border-radius:3px; color:#fff; background:#444; border:1px solid #ababab;}.remotehint{z-index:1; position:absolute; top:1px; margin-left:auto; left:50%; margin-left:-200px; width:400px; border-radius:5px; padding:4px; -moz-border-radius:5px; border:1px solid #DEEEFC; background:#F2F9FF; text-align:center; color:#3F70BA; display:inline;}

View File

@@ -1,15 +0,0 @@
/***************************************************************************
* This file is part of Roundcube "##PLUGIN##" plugin.
*
* Your are not allowed to distribute this file or parts of it.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Copyright (c) 2012 - ##YEAR## Roland 'Rosali' Liebl - all rights reserved
* dev-team [at] myroundcube [dot] com
* http://myroundcube.com
***************************************************************************/
select.deco{}#taskbar .remotehint{position:absolute; top:52px; left:50%; margin-left:-200px; width:400px; padding:0px; border:1px solid #DEEEFC; background-color:#F2F9FF; text-align:center; font-size:10px; color:#3F70BA;}