Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d667518d1f | ||
|
|
5ad75ce989 | ||
|
|
dbadde3333 | ||
|
|
b499688318 | ||
|
|
6cfbeab7f0 | ||
|
|
b10f3625c2 | ||
|
|
f28fb5bb58 | ||
|
|
1b424b4348 | ||
|
|
6705312240 | ||
|
|
05ea494fa6 | ||
|
|
5a704f2717 | ||
|
|
01edffa66b | ||
|
|
9367409f36 | ||
|
|
bbf28eed57 | ||
|
|
ec71910156 | ||
|
|
f700593730 | ||
|
|
9db4f48593 | ||
|
|
2b9c43858e | ||
|
|
95716183d7 | ||
|
|
40e7f5664e | ||
|
|
ea62869891 |
@@ -3,4 +3,9 @@ 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.*
|
||||
*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
38
SQL/mysql.initial.sql
Normal 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)
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
11
SQL/postgres/2016052000.sql
Normal file
11
SQL/postgres/2016052000.sql
Normal 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;
|
||||
@@ -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();
|
||||
$('#plugin-ident_switch-account').show();
|
||||
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 });
|
||||
|
||||
167
ident_switch.php
167
ident_switch.php
@@ -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;
|
||||
|
||||
$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),
|
||||
$rc->user->ID,
|
||||
$args['id']
|
||||
);
|
||||
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,
|
||||
$fLabel,
|
||||
$fHost,
|
||||
$fPort,
|
||||
$fUser,
|
||||
$fPass,
|
||||
$fDelim,
|
||||
$rc->user->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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
53
localization/ru_RU.inc
Normal 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.';
|
||||
@@ -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;}
|
||||
@@ -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;}
|
||||
@@ -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;}
|
||||
Reference in New Issue
Block a user