mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 08:57:03 +03:00
CardDAV (pre-release)
This commit is contained in:
parent
7a8fffede8
commit
639d8c58f6
38 changed files with 525 additions and 207 deletions
|
|
@ -290,11 +290,12 @@ class Http
|
|||
|
||||
/**
|
||||
* @param bool $bWithRemoteUserData = false
|
||||
* @param bool $bRemoveWWW = true
|
||||
* @param bool $bWithoutWWW = true
|
||||
* @param bool $bWithoutPort = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHost($bWithRemoteUserData = false, $bRemoveWWW = true)
|
||||
public function GetHost($bWithRemoteUserData = false, $bWithoutWWW = true, $bWithoutPort = false)
|
||||
{
|
||||
$sHost = $this->GetServer('HTTP_HOST', '');
|
||||
if (0 === \strlen($sHost))
|
||||
|
|
@ -307,7 +308,7 @@ class Http
|
|||
? $sName : $sName.':'.$iPort;
|
||||
}
|
||||
|
||||
if ($bRemoveWWW)
|
||||
if ($bWithoutWWW)
|
||||
{
|
||||
$sHost = 'www.' === \substr(\strtolower($sHost), 0, 4) ? \substr($sHost, 4) : $sHost;
|
||||
}
|
||||
|
|
@ -318,6 +319,11 @@ class Http
|
|||
$sHost = (0 < \strlen($sUser) ? $sUser.'@' : '').$sHost;
|
||||
}
|
||||
|
||||
if ($bWithoutPort)
|
||||
{
|
||||
$sHost = \preg_replace('/:[\d]+$/', '', $sHost);
|
||||
}
|
||||
|
||||
return $sHost;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -930,14 +930,35 @@ class Actions
|
|||
$oAccount = $this->getAccountFromToken(false);
|
||||
if ($oAccount instanceof \RainLoop\Account)
|
||||
{
|
||||
$oPab = $this->PersonalAddressBookProvider($oAccount);
|
||||
|
||||
|
||||
$aResult['Auth'] = true;
|
||||
$aResult['Email'] = $oAccount->Email();
|
||||
$aResult['IncLogin'] = $oAccount->IncLogin();
|
||||
$aResult['OutLogin'] = $oAccount->OutLogin();
|
||||
$aResult['AccountHash'] = $oAccount->Hash();
|
||||
$aResult['ChangePasswordIsAllowed'] = $this->ChangePasswordProvider()->PasswordChangePossibility($oAccount);
|
||||
$aResult['ContactsIsAllowed'] = $this->PersonalAddressBookProvider($oAccount)->IsActive();
|
||||
$aResult['ContactsSharingIsAllowed'] = $this->PersonalAddressBookProvider($oAccount)->IsSharingAllowed();
|
||||
$aResult['ContactsIsAllowed'] = $oPab->IsActive();
|
||||
$aResult['ContactsSharingIsAllowed'] = $oPab->IsSharingAllowed();
|
||||
|
||||
$aResult['ContactsSyncIsAllowed'] = (bool) $oConfig->Get('contacts', 'allow_sync', false);
|
||||
$aResult['ContactsSyncServer'] = '';
|
||||
$aResult['ContactsSyncUser'] = '';
|
||||
$aResult['ContactsSyncPassword'] = '';
|
||||
$aResult['ContactsSyncPabUrl'] = '';
|
||||
|
||||
if ($aResult['ContactsSyncIsAllowed'])
|
||||
{
|
||||
$aResult['ContactsSyncServer'] = $this->Http()->GetHost(false, true, true);
|
||||
$aResult['ContactsSyncUser'] = $oAccount->ParentEmailHelper();
|
||||
$aResult['ContactsSyncPassword'] = $oPab->GetUserHashByEmail($aResult['ContactsSyncUser'], true);
|
||||
|
||||
$sUrl = \rtrim(\trim($this->Http()->GetScheme().'://'.$this->Http()->GetHost(true, false).$this->Http()->GetPath()), '/\\');
|
||||
$sUrl = \preg_replace('/index\.php(.*)$/i', '', $sUrl);
|
||||
|
||||
$aResult['ContactsSyncPabUrl'] = $sUrl.'/index.php/dav/addressbooks/'.$oAccount->ParentEmailHelper().'/default/';
|
||||
}
|
||||
|
||||
$oSettings = $this->SettingsProvider()->Load($oAccount);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ class PdoPersonalAddressBook
|
|||
*/
|
||||
public function GetUserUidByEmail($sEmail)
|
||||
{
|
||||
$this->Sync();
|
||||
|
||||
$iId = $this->getUserId($sEmail);
|
||||
return 0 < $iId ? (string) $iId : '';
|
||||
}
|
||||
|
|
@ -98,6 +100,8 @@ class PdoPersonalAddressBook
|
|||
*/
|
||||
public function GetCtagByEmail($sEmail)
|
||||
{
|
||||
$this->Sync();
|
||||
|
||||
$sResult = '0';
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
if (0 < $iUserID)
|
||||
|
|
@ -126,11 +130,13 @@ class PdoPersonalAddressBook
|
|||
*/
|
||||
public function GetUserHashByEmail($sEmail, $bCreate = false)
|
||||
{
|
||||
$this->Sync();
|
||||
|
||||
$sHash = '';
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
if (0 < $iUserID)
|
||||
{
|
||||
$oStmt = $this->prepareAndExecute('SELECT pass_hash FROM rainloop_pab_users_hashes WHERE id_user = :id_user LIMIT 1',
|
||||
$oStmt = $this->prepareAndExecute('SELECT pass_hash FROM rainloop_pab_users WHERE id_user = :id_user LIMIT 1',
|
||||
array(':id_user' => array($iUserID, \PDO::PARAM_INT)));
|
||||
|
||||
if ($oStmt)
|
||||
|
|
@ -142,14 +148,15 @@ class PdoPersonalAddressBook
|
|||
}
|
||||
else if ($bCreate)
|
||||
{
|
||||
$this->prepareAndExecute('INSERT INTO rainloop_pab_users_hashes (id_user, pass_hash) VALUES (:id_user, :pass_hash);',
|
||||
$this->prepareAndExecute('INSERT INTO rainloop_pab_users (id_user, email, pass_hash) VALUES (:id_user, :email, :pass_hash);',
|
||||
array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
':email' => array($sEmail, \PDO::PARAM_STR),
|
||||
':pass_hash' => array(\md5($sEmail.\microtime(true)), \PDO::PARAM_STR)
|
||||
)
|
||||
);
|
||||
|
||||
$this->GetUserHashByEmail($sEmail, false);
|
||||
$sHash = $this->GetUserHashByEmail($sEmail, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -305,6 +312,7 @@ class PdoPersonalAddressBook
|
|||
*/
|
||||
public function DeleteContacts($sEmail, $aContactIds)
|
||||
{
|
||||
$this->Sync();
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
|
||||
$aContactIds = \array_filter($aContactIds, function (&$mItem) {
|
||||
|
|
@ -1239,8 +1247,9 @@ SQLITEINITIAL;
|
|||
'ALTER TABLE rainloop_pab_contacts ADD carddav_data MEDIUMTEXT;',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_hash varchar(128) NOT NULL DEFAULT \'\';',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_size int UNSIGNED NOT NULL DEFAULT 0;',
|
||||
'CREATE TABLE IF NOT EXISTS rainloop_pab_users_hashes (
|
||||
'CREATE TABLE IF NOT EXISTS rainloop_pab_users (
|
||||
id_user int UNSIGNED NOT NULL,
|
||||
email varchar(128) NOT NULL,
|
||||
pass_hash varchar(128) NOT NULL
|
||||
)/*!40000 ENGINE=INNODB */;'
|
||||
)
|
||||
|
|
@ -1253,8 +1262,9 @@ SQLITEINITIAL;
|
|||
'ALTER TABLE rainloop_pab_contacts ADD carddav_data TEXT;',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_hash varchar(128) NOT NULL DEFAULT \'\';',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_size integer NOT NULL DEFAULT 0;',
|
||||
'CREATE TABLE rainloop_pab_users_hashes (
|
||||
'CREATE TABLE rainloop_pab_users (
|
||||
id_user integer NOT NULL,
|
||||
email varchar(128) NOT NULL,
|
||||
pass_hash varchar(128) NOT NULL
|
||||
);'
|
||||
)
|
||||
|
|
@ -1267,8 +1277,9 @@ SQLITEINITIAL;
|
|||
'ALTER TABLE rainloop_pab_contacts ADD carddav_data text;',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_hash text NOT NULL DEFAULT \'\';',
|
||||
'ALTER TABLE rainloop_pab_contacts ADD carddav_size integer NOT NULL DEFAULT 0;',
|
||||
'CREATE TABLE rainloop_pab_users_hashes (
|
||||
'CREATE TABLE rainloop_pab_users (
|
||||
id_user integer NOT NULL,
|
||||
email text NOT NULL,
|
||||
pass_hash text NOT NULL
|
||||
);'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal" data-bind="visible: contactsSupported">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
Contacts
|
||||
</div>
|
||||
|
|
@ -23,12 +22,15 @@
|
|||
<i data-bind="css: contactsSharing() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
|
||||
Allow contacts sharing
|
||||
</label>
|
||||
<br />
|
||||
<label data-bind="click: function () { contactsSync(!contactsSync()); }">
|
||||
<i data-bind="css: contactsSync() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
|
||||
Allow contacts sync (CardDAV)
|
||||
</label>
|
||||
<a href="http://rainloop.net/docs/carddav/" target="_blank">read about web server configuration</a>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Type
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-accounts">
|
||||
<div class="b-settings-accounts g-ui-user-select-none">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_ACCOUNTS/LEGEND_ACCOUNTS"></span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-general">
|
||||
<div class="b-settings-general g-ui-user-select-none">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CHANGE_PASSWORD/LEGEND_CHANGE_PASSWORD"></span>
|
||||
|
|
|
|||
66
rainloop/v/0.0.0/app/templates/Views/SettingsContacts.html
Normal file
66
rainloop/v/0.0.0/app/templates/Views/SettingsContacts.html
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<div class="b-settings-contacts">
|
||||
<div class="form-horizontal g-ui-user-select-none">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LEGEND_CONTACTS"></span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label data-bind="click: function () { contactsAutosave(!contactsAutosave()); }">
|
||||
<i data-bind="css: contactsAutosave() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
|
||||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LABEL_CONTACTS_AUTOSAVE"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal" data-bind="visible: allowContactsSync">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LEGEND_MOBILE_SYNC"></span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" style="padding-top: 0;">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LABEL_SYNC_SERVER"></span>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<strong data-bind="text: contactsSyncServer"></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" style="padding-top: 0;">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LABEL_SYNC_USERNAME"></span>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<strong data-bind="text: contactsSyncUser"></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" style="padding-top: 0;">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LABEL_SYNC_PASSWORD"></span>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<div data-bind="visible: showPassword">
|
||||
<strong style="color:red" data-bind="text: contactsSyncPass"></strong>
|
||||
</div>
|
||||
<span class="g-ui-link i18n" data-bind="visible: !showPassword(), click: toggleShowPassword"
|
||||
data-i18n-text="SETTINGS_CONTACTS/LINK_SHOW"></span>
|
||||
<span class="g-ui-link i18n" data-bind="visible: showPassword, click: toggleShowPassword"
|
||||
data-i18n-text="SETTINGS_CONTACTS/LINK_HIDE"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div class="alert alert-info span8" style="margin-left: 0">
|
||||
<p>
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/DESC_FULL_PAB_URL"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="i18n" data-i18n-text="SETTINGS_CONTACTS/LABEL_DESC_PAB"></span>:
|
||||
<br />
|
||||
<a href="javascript:void(0);" target="_blank" data-bind="text: contactsSyncPabUrl, attr: {'href': contactsSyncPabUrl}"></a>
|
||||
</p>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-folders" data-bind="css: { 'ignore-folder-subscribe': !useImapSubscribe }">
|
||||
<div class="b-settings-folders g-ui-user-select-none" data-bind="css: { 'ignore-folder-subscribe': !useImapSubscribe }">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FOLDERS/LEGEND_FOLDERS"></span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-general">
|
||||
<div class="b-settings-general g-ui-user-select-none">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_GENERAL/LEGEND_GENERAL"></span>
|
||||
|
|
@ -64,20 +64,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal" data-bind="visible: allowContacts">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_GENERAL/LEGEND_CONTACTS"></span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label data-bind="click: function () { contactsAutosave(!contactsAutosave()); }">
|
||||
<i data-bind="css: contactsAutosave() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
|
||||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_GENERAL/LABEL_CONTACTS_AUTOSAVE"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_GENERAL/LABEL_VIEW_OPTIONS"></span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-identities">
|
||||
<div class="b-settings-identities g-ui-user-select-none">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_IDENTITIES/LEGEND_IDENTITY"></span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings b-settins-right g-ui-user-select-none">
|
||||
<div class="b-settings b-settins-right">
|
||||
<div class="b-toolbar">
|
||||
<div class="btn-toolbar">
|
||||
<a class="btn button-back" data-bind="click: backToMailBoxClick">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-social">
|
||||
<div class="b-settings-social g-ui-user-select-none">
|
||||
<div class="form-horizontal" data-bind="visible: googleEnable">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_SOCIAL/LEGEND_GOOGLE"></span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="b-settings-themes">
|
||||
<div class="b-settings-themes g-ui-user-select-none">
|
||||
<div class="form-horizontal">
|
||||
<div class="legend">
|
||||
<span class="i18n" data-i18n-text="SETTINGS_THEMES/LEGEND_THEMES"></span>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<div class="b-system-drop-down g-ui-user-select-none">
|
||||
<div class="b-toolbar">
|
||||
<div class="btn-toolbar">
|
||||
<div class="btn-group pull-right">
|
||||
<!-- <div class="btn-group pull-right">
|
||||
<a class="btn btn-narrow" data-bind="click: logoutClick">
|
||||
<i class="icon-power"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group pull-right">
|
||||
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-ellipsis btn-block dropdown-toggle system-dropdown" data-placement="left" data-toggle="dropdown"
|
||||
data-tooltip-class="tooltip-big" data-bind="tooltip2: emailTitle">
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<span class="i18n" data-i18n-text="TOP_TOOLBAR/BUTTON_SETTINGS"></span>
|
||||
</a>
|
||||
</li>
|
||||
<!--
|
||||
|
||||
<li class="divider"></li>
|
||||
<li class="e-item">
|
||||
<a class="e-link" data-bind="click: logoutClick">
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
<span class="i18n" data-i18n-text="TOP_TOOLBAR/BUTTON_LOGOUT"></span>
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue