Compare commits

...
520 Commits
Author SHA1 Message Date
Ludovic Marcotte 2c9c1e0d01 (fix) support Squeeze + minor cleanups 2017-07-05 11:08:00 -04:00
Francis Lachapelle f6d79712e2 Update ChangeLog 2017-07-05 10:51:35 -04:00
Francis Lachapelle c0db64e0f2 Preparation for release 3.2.10 2017-07-05 10:49:34 -04:00
Francis Lachapelle 43d85f8bc4 Use xsltproc instead of fop to generate XSL-FO 2017-07-05 10:44:27 -04:00
Francis Lachapelle 5aa74ca0ad (js) Update CKEditor to version 4.7.1 2017-07-05 10:06:05 -04:00
InverseBot 5d98112a7a (js/css) Update generated files 2017-07-05 01:25:31 -04:00
Francis Lachapelle c48750c6f2 (js) Fix mail composition from mailto link 2017-07-04 17:23:00 -04:00
Ludovic Marcotte b7dac4db9f Updated NEWS 2017-07-04 13:20:02 -04:00
Ludovic Marcotte 579ab68e19 (fix) silence sogo-ealarms-notify verbose output (fixes #4170) 2017-07-04 13:15:29 -04:00
Ludovic Marcotte 0c82ad5944 Updated NEWS 2017-07-04 11:02:44 -04:00
Ludovic Marcotte 22c078ee76 (fix) enable S/MIME even when using GNU TLS (fixes #4201) 2017-07-04 11:00:06 -04:00
Francis Lachapelle 721428c88f (js) Create list from selected cards
Fixes #3561
2017-07-04 10:10:00 -04:00
Ludovic Marcotte 07fa202523 (fix) respect disabled state of sending rate-limiting (fixes #4198) 2017-07-04 09:58:20 -04:00
Ludovic Marcotte 919d1ef6be (fix) avoid advertising EAS 16 support until libwbxml is fixed 2017-07-04 09:26:08 -04:00
InverseBot 3927494393 (js/css) Update generated files 2017-07-04 01:24:12 -04:00
InverseBot 14b902241d (js/css) Update generated files 2017-06-30 01:28:54 -04:00
Ludovic Marcotte fa7aba89c2 (doc) improve iOS doc 2017-06-29 15:41:23 -04:00
Francis Lachapelle 7785c1c142 (css,js) Update md to v1.1.4-master-75237c6 2017-06-29 11:17:22 -04:00
Francis Lachapelle d9dafd3d14 (js) Don't explode card when no email defined 2017-06-29 10:49:15 -04:00
InverseBot df8c00089b (js/css) Update generated files 2017-06-29 01:29:10 -04:00
Francis Lachapelle 741e639960 (i18n) Update translations 2017-06-28 14:16:26 -04:00
Francis Lachapelle 9f96639e6f Ignore errors of nonexistent special mailboxes
Fixes #4177
2017-06-28 14:01:52 -04:00
Francis Lachapelle ee68cf6ed5 (js) Add missing ui-router map files
Fixes #4209
2017-06-28 12:06:05 -04:00
Francis Lachapelle 8662dd199d (js) Add missing timezone list in Preferences 2017-06-28 12:00:36 -04:00
Francis Lachapelle 2d1c2b2239 Update NEWS file 2017-06-28 11:01:21 -04:00
Francis Lachapelle 863510e707 (fix) Update settings of active user only
Fixes #3988
2017-06-28 10:57:18 -04:00
Francis Lachapelle 3ce28b7316 (js) Use more one-time bindings 2017-06-27 22:24:07 -04:00
InverseBot b0e0950d12 (js/css) Update generated files 2017-06-23 01:28:37 -04:00
Francis Lachapelle e8ec8180a8 (js) Use more one-time bindings in Calendar module 2017-06-22 11:56:16 -04:00
Francis Lachapelle 9bde9b66ef Improve identification of preferred elements
Fixes #799
2017-06-22 11:56:16 -04:00
Ludovic Marcotte 7f00afcef5 (fix) check cache before using it (fixes #3988) 2017-06-22 10:20:54 -04:00
InverseBot 362d6d521f (js/css) Update generated files 2017-06-21 01:27:31 -04:00
Francis Lachapelle e1bc458d46 (js) Don't save form when invalid
Fixes #3793
2017-06-20 15:25:07 -04:00
InverseBot ade945219f (js/css) Update generated files 2017-06-17 01:26:44 -04:00
Francis Lachapelle 6c654e0f90 (js) Fix validation in Sieve filter editor
Fixes #4200
2017-06-16 16:37:17 -04:00
Ludovic Marcotte ca43e7d9ca (fix) added doc to sogo-tool manage-eas + did cleanups (fixes #3967) 2017-06-16 13:25:15 -04:00
Ludovic Marcotte 0a155d6f67 (fix) missing import 2017-06-16 13:24:24 -04:00
InverseBot c9dded0947 (js/css) Update generated files 2017-06-16 01:30:58 -04:00
Francis Lachapelle d72c614d29 (js) Fix edition of mail tags 2017-06-15 16:04:47 -04:00
Ludovic Marcotte 157d3050bf Deleted old tests 2017-06-15 11:24:32 -04:00
Ludovic Marcotte 8a50ccdab4 Updated NEWS 2017-06-15 11:23:51 -04:00
Ludovic Marcotte 99fff30489 (fix) don't include task folders over EAS if we are hiding them (fixes #4164) 2017-06-15 11:21:41 -04:00
InverseBot ef122b0f39 (js/css) Update generated files 2017-06-15 01:28:00 -04:00
Francis Lachapelle b6b8f7a0fb Improve display of component comments, card notes 2017-06-14 20:41:18 -04:00
Francis Lachapelle 8701d2c26c (js) Remove inline user settings for Contacts 2017-06-14 20:41:18 -04:00
Francis Lachapelle 5080482507 (html) Remove useless space from card editor 2017-06-14 20:41:18 -04:00
Ludovic Marcotte 392cad1cbb Updated NEWS 2017-06-14 15:53:49 -04:00
Ludovic Marcotte 248cea87e8 (feat) initial pass at generalized stress tests 2017-06-14 14:41:01 -04:00
Francis Lachapelle 7464c2e680 (js) Support backspace AND delete keys 2017-06-14 13:38:40 -04:00
Francis Lachapelle 67b9ef0b8b (js) Fix mailbox deletion from the hot key 2017-06-14 13:24:08 -04:00
Ludovic Marcotte 9b2527ce6d (fix) provide mininum values for recurrences 2017-06-13 15:05:04 -04:00
InverseBot 67d4896bc7 (js/css) Update generated files 2017-06-10 02:08:54 -04:00
Ludovic Marcotte a86f8a8a0a (fix) email alarms are sent too many times (fixes #4100) 2017-06-09 15:17:32 -04:00
Ludovic Marcotte 5fd8c9d2d0 (doc) updates for MySQL's max_allowed_packet parameter (fixes #4119 and #4142) 2017-06-09 11:19:57 -04:00
Ludovic Marcotte aff5d53b1c (fix) improvements for Drafts handling 2017-06-09 10:01:11 -04:00
Francis Lachapelle b3f541b87e Sanitize whitelisted attributes of HTML tags 2017-06-05 15:14:48 -04:00
Francis Lachapelle 2604e2bf59 Sanity check when user's session has expired 2017-06-05 10:23:59 -04:00
InverseBot dc9eaa164d (js/css) Update generated files 2017-06-03 01:24:59 -04:00
Francis Lachapelle b8f54dd8e8 (css,js) Update md to v1.1.4-master-e1345ae 2017-06-02 14:20:40 -04:00
InverseBot 15ab809c38 (js/css) Update generated files 2017-06-02 02:16:11 -04:00
Ludovic Marcotte bb04f97570 Updated NEWS 2017-06-01 16:11:34 -04:00
Ludovic Marcotte 6f56522f89 (feat) first pas at EAS v16 support and save in drafts 2017-06-01 16:07:34 -04:00
Ludovic Marcotte 6e04a2d99c (feat) can now discard incoming mails during vacation 2017-06-01 14:49:09 -04:00
Francis Lachapelle e8e0df8b53 Expose user settings and defaults inline (cont'd) 2017-06-01 13:50:46 -04:00
Francis Lachapelle 72d2152b20 (i18n) Add missing strings in Contacts module 2017-06-01 13:49:00 -04:00
Francis Lachapelle 89bfa0c536 Expose user's settings and defaults inline
This improves performance by removing two AJAX calls and a lot of
JavaScript promises.
2017-06-01 13:48:45 -04:00
Francis Lachapelle 1fa056bb25 Update README for new Latvian translation 2017-06-01 13:48:44 -04:00
InverseBot a19d1573d3 (js/css) Update generated files 2017-06-01 01:25:44 -04:00
Francis Lachapelle c8e90b4abd (css) Improve sgImageGallery for small devices
Also include md-truncate directive from ng-material.
2017-05-31 09:40:22 -04:00
Francis Lachapelle e4d0ce6090 (i18n) Fix Lithuanian typo 2017-05-31 06:36:03 -04:00
Francis Lachapelle a33bd62343 Add Latvian (lv) translation (cont'd) 2017-05-31 06:36:03 -04:00
InverseBot 0738896540 (js/css) Update generated files 2017-05-31 00:27:22 -04:00
Francis Lachapelle 34a6a8960a Add Latvian (lv) translation 2017-05-30 16:19:44 -04:00
Francis Lachapelle 02684127dd Cleanup UI/WebServerResources/GNUmakefile 2017-05-30 14:56:35 -04:00
Ludovic Marcotte 6a8345c2c8 (fix) fixed typos in tools' help (fixes #4175) 2017-05-30 14:47:23 -04:00
Ludovic Marcotte 9dae52a719 (fix) sanity check when no defaults are found (fixes #4179) 2017-05-30 14:44:43 -04:00
Ludovic Marcotte f87797d61e Updated NEWS 2017-05-30 13:16:54 -04:00
Ludovic Marcotte 29dfc75fe9 (fix) remove any trailing cr (fixes #4172) 2017-05-30 13:15:04 -04:00
Francis Lachapelle af2507a689 Newly subscribed calendars are excluded from FB
Fixes #3354
2017-05-30 09:27:27 -04:00
Ludovic Marcotte 2b90ff70fa (feat) added custom fields support from Thunderbird's address book 2017-05-30 09:12:13 -04:00
InverseBot 43141a48cf (js/css) Update generated files 2017-05-30 01:27:54 -04:00
Francis Lachapelle 0355f66e96 (js) New ImageGallery ng service 2017-05-29 15:19:03 -04:00
Francis Lachapelle 3049af066b (css) Remove sgColorPicker in grid-list.scss 2017-05-29 14:54:54 -04:00
Francis Lachapelle b00fc756e6 (js) Cleanup dependencies of sgMailboxListItem 2017-05-29 14:51:51 -04:00
Francis Lachapelle 555b7303d1 (js) New images viewer for Mail module 2017-05-29 14:03:59 -04:00
Ludovic Marcotte 0a990ff66b (doc) replaced localhost with 127.0.0.1 to avoid IPv6 errors 2017-05-26 15:44:23 -04:00
Francis Lachapelle e591c9b3cf (doc) Fix rendering of Installation Guide 2017-05-25 14:41:05 -04:00
InverseBot acc6da4c15 (js/css) Update generated files 2017-05-25 01:24:14 -04:00
Francis Lachapelle 3f3f58dc9f (js) Fix card loading via router 2017-05-24 13:56:20 -04:00
Francis Lachapelle e30358aeaa (css) Fix responsive condition of login page 2017-05-24 11:55:24 -04:00
Francis Lachapelle 28e0db4adf Fix adding list members with multiple emails 2017-05-24 11:37:35 -04:00
Francis Lachapelle 92137de325 (doc) Fix IMAP server URL with TLS 2017-05-24 08:33:22 -04:00
InverseBot ad90d666ca (js/css) Update generated files 2017-05-24 01:22:20 -04:00
Francis Lachapelle 8678949c87 (js) Improve performance of color picker
Lower the number of watchers.
2017-05-23 15:43:47 -04:00
InverseBot 8f005b90f5 (js/css) Update generated files 2017-05-21 01:18:15 -04:00
InverseBot 49183bd1fb (js/css) Update generated files 2017-05-20 01:12:37 -04:00
Francis Lachapelle a26970b33b (js) Remove bindings on message flags in directive 2017-05-19 22:20:20 -04:00
Francis Lachapelle f2af5e9f87 Improve display of tasks status 2017-05-19 12:13:01 -04:00
Francis Lachapelle c24474b197 (js) Add missing injection in component editor 2017-05-19 08:56:10 -04:00
Francis Lachapelle ec02efe873 (js) No one-time bindings inside virtual-repeater 2017-05-19 07:53:05 -04:00
Francis Lachapelle 8dc2cfc2dc Silent sogo-tool expire-sessions cronjob
Fixes #4170
2017-05-19 07:46:18 -04:00
InverseBot ce5db84996 (js/css) Update generated files 2017-05-19 01:24:40 -04:00
Francis Lachapelle 41967d3eec Respect languages preferences on login page
Fixes #4169
2017-05-18 22:28:05 -04:00
Francis Lachapelle aee42f76f0 (js) Use one-time bindings in ACLs and sidenav 2017-05-18 15:40:11 -04:00
Francis Lachapelle 28ae2fd58a (js) Review Mail module to decrease watchers 2017-05-18 15:31:38 -04:00
Ludovic Marcotte 083be7e89f Fixed typo 2017-05-17 09:56:16 -04:00
Ludovic Marcotte 99510f4646 Updated NEWS 2017-05-17 09:47:53 -04:00
Ludovic Marcotte 334765c977 (feat) now able to subscribe/unsubscribe folders using sogo-tool 2017-05-17 09:44:34 -04:00
InverseBot 7207925362 (js/css) Update generated files 2017-05-13 01:24:30 -04:00
Francis Lachapelle c9b9150b96 Update ChangeLog 2017-05-09 09:06:22 -04:00
Francis Lachapelle 4d490d0f1e Preparation for release 3.2.9 2017-05-09 09:04:31 -04:00
Francis Lachapelle bc23130f9b (i18n) Update translations 2017-05-09 09:00:33 -04:00
InverseBot 28bc489c1a (js/css) Update generated files 2017-05-09 01:22:56 -04:00
Francis Lachapelle 650f337c41 (js/css) Update generated files 2017-05-08 16:08:22 -04:00
Francis Lachapelle 8de9b8ff53 Update time zones to version 2017b 2017-05-08 16:00:10 -04:00
Francis Lachapelle 8b812ba4f0 (js) Minor JavaScript code cleanup 2017-05-08 15:46:48 -04:00
Francis Lachapelle 836700fb7e (js) Improve CAS handling 2017-05-08 15:43:10 -04:00
Francis Lachapelle ba583f41b1 (i18n) Update translations 2017-05-08 15:06:31 -04:00
Francis Lachapelle 0e82550f6b Update SOGoParentFolder.h 2017-05-08 14:44:13 -04:00
Francis Lachapelle 0185ba9d46 Fix mail delegation of pristine user accounts
Fixes #4160
2017-05-08 11:23:32 -04:00
Ludovic Marcotte 9700b93ad1 Updated NEWS 2017-05-08 10:46:39 -04:00
Ludovic Marcotte 63cb80142b (fix) make sure to use crypt as the scheme for md5/sha256/sha512 (fixes #4137) 2017-05-08 10:44:12 -04:00
InverseBot c3ef225a02 (js/css) Update generated files 2017-05-08 01:23:36 -04:00
InverseBot b42876bb0a (js/css) Update generated files 2017-05-07 01:17:20 -04:00
InverseBot da4033eeab (js/css) Update generated files 2017-05-04 01:17:26 -04:00
Francis Lachapelle f1329a3d36 (i18n) Update German translation 2017-05-02 09:56:30 -04:00
Francis Lachapelle b46781c693 Silent sogo-ealarms-notify
Fixes #4157
2017-04-27 09:40:24 -04:00
Francis Lachapelle ef5728dcaf Properly honor "include in freebusy"
Fixes #3354
2017-04-27 09:38:07 -04:00
Francis Lachapelle 663a0b60dd (feat) Configurable Web animation level 2017-04-25 16:35:39 -04:00
Francis Lachapelle 59dbef5ee7 Avoid duplicated emails in LDAP-based addressbook
Fixes #4129
2017-04-25 14:49:29 -04:00
InverseBot 4caff58918 (js/css) Update generated files 2017-04-25 01:18:12 -04:00
Francis Lachapelle 634cbe3d1b (js) Support SOGoLDAPContactInfoAttrbute 2017-04-24 16:15:39 -04:00
Francis Lachapelle 3d0c958a19 (js) Keep form pristine when changing passwords
Fixes #4138
2017-04-24 12:08:15 -04:00
Francis Lachapelle da44afdcf5 (i18n) Update translations 2017-04-24 11:37:49 -04:00
InverseBot 11f847cdfb (js/css) Update generated files 2017-04-22 01:18:32 -04:00
Francis Lachapelle 5f71ee4d52 (doc) Typo 2017-04-21 16:02:10 -04:00
Francis Lachapelle 68eae92d2d (doc) Exclude GNUstep packages from EPEL 2017-04-21 15:32:33 -04:00
Ludovic Marcotte 9459185059 Updated NEWS 2017-04-21 15:31:26 -04:00
Ludovic Marcotte a9763e94a4 (feat) added photo support in GAL search ops 2017-04-21 15:29:34 -04:00
Ludovic Marcotte 5c573b9a76 (fix) small fixes over previous commit 2017-04-21 14:12:48 -04:00
Ludovic Marcotte 513d81eb59 (fix) LDIF to vCard conversion for non-handled multi-value attributes (fixes #4086) 2017-04-21 12:31:54 -04:00
Francis Lachapelle 2b4e357da6 (js) Improve handling of IMAP timeout handling
For external accounts only.
2017-04-21 11:58:52 -04:00
Ludovic Marcotte ab50a41a86 (fix) email reminders sent multiple times (fixes #4100) 2017-04-21 08:49:56 -04:00
Ludovic Marcotte 7582ec8462 Updated comment 2017-04-20 14:35:44 -04:00
Ludovic Marcotte dd6b77a25b Updated NEWS 2017-04-20 14:31:26 -04:00
Ludovic Marcotte 0091ff749a (fix) handle properly windows-1255 charset (fixes #4124) 2017-04-20 14:29:15 -04:00
InverseBot c09dff3fc8 (js/css) Update generated files 2017-04-13 01:24:28 -04:00
Ludovic Marcotte 8a59180c0e Updated NEWS 2017-04-12 16:37:14 -04:00
Ludovic Marcotte d87dc6cdf2 (fix) enhance display of all-day invitations (fixes #4145)
Conflicts:
	SoObjects/Appointments/SOGoAptMailNotification.m
2017-04-12 16:36:41 -04:00
Francis Lachapelle 0af81b0831 (email alarms) Fix recipient header encoding 2017-04-12 16:22:15 -04:00
Francis Lachapelle 6fd9927092 (js) Fix email reminder with attendees
Fixes #4115
2017-04-12 14:56:38 -04:00
Francis Lachapelle 8bcda19799 (web) Fix renaming a mailbox with special chars 2017-04-12 13:41:24 -04:00
Ludovic Marcotte 5570d28d12 Updated NEWS 2017-04-12 13:02:10 -04:00
Ludovic Marcotte b8369ddb37 (fix) don't send IMIP invitation request/update for ALL EAS clients (fixes #4022) 2017-04-12 13:01:01 -04:00
Ludovic Marcotte e1ea6392c2 (fix) set RSVP when sending events invite 2017-04-12 12:59:53 -04:00
Ludovic Marcotte 011e112a1a Updated NEWS 2017-04-12 09:01:32 -04:00
Ludovic Marcotte 7d396a51f5 (feat) email alarms now have pretty formatting (fixes #805) 2017-04-12 08:59:29 -04:00
InverseBot dbf5039011 (js/css) Update generated files 2017-04-12 01:20:37 -04:00
Francis Lachapelle 76e6c064f7 Improve IMAP error handling in Mailer module 2017-04-11 15:42:36 -04:00
Francis Lachapelle 04f930dba5 (js) Always show center list on small devices 2017-04-11 12:00:00 -04:00
Francis Lachapelle 08fcee67bd Improve IMAP error handling in Mailer module 2017-04-11 11:47:47 -04:00
Ludovic Marcotte cc9602fbc8 Updated NEWS 2017-04-11 10:15:58 -04:00
Ludovic Marcotte c92d489017 (fix) remove over EAS alarms if we don't want them (fixes #4059) 2017-04-11 10:13:56 -04:00
Ludovic Marcotte 4cf59cd92e Updated NEWS 2017-04-07 14:18:20 -04:00
Ludovic Marcotte c4ad338aed (fix) initialize variable to avoid strange nil-return value on invocation (fixes #4048) 2017-04-07 14:16:18 -04:00
Ludovic Marcotte c8708d9164 Updated NEWS 2017-04-07 13:45:07 -04:00
Ludovic Marcotte 9bf7247835 (fix) correctly set flags when ReplaceMime is set (fixes #4133) 2017-04-07 13:43:18 -04:00
Francis Lachapelle ed3f794226 Fix attachment path when inside multiple parts 2017-04-06 14:31:41 -04:00
Ludovic Marcotte b9f4947f8a (fix) check if found before changing location 2017-04-06 14:24:25 -04:00
Ludovic Marcotte f83d6a20a1 (fix) protect ourself from broken SOPE/SOGo installs (fixes #4117) 2017-04-06 11:02:59 -04:00
Francis Lachapelle 8ff189229b [web] Fix exception when partstate is not known 2017-04-05 16:22:28 -04:00
Francis Lachapelle 4c1de4cecc Update NEWS file 2017-04-05 14:00:02 -04:00
InverseBot a7254fe4dd (js/css) Update generated files 2017-04-04 01:25:28 -04:00
Ludovic Marcotte 308938dcfa Updated NEWS 2017-03-29 10:20:59 -04:00
Ludovic Marcotte c11d961bf3 (fix) avoid escaping values that are quoted (fixes #3296) 2017-03-29 10:18:38 -04:00
InverseBot 4e82820db7 (js/css) Update generated files 2017-03-25 01:31:35 -04:00
Ludovic Marcotte 26dac618d0 (fix) more fixes for #3905 2017-03-24 12:38:02 -04:00
Ludovic Marcotte f1cc36b533 (fix) more fixes for #3905 2017-03-24 12:37:55 -04:00
Francis Lachapelle cf07f5746c Update ChangeLog 2017-03-24 09:46:32 -04:00
Francis Lachapelle a328f022cb (css) Update default theme 2017-03-24 09:45:56 -04:00
Francis Lachapelle 46c7af5fdd (js/css) Update generated files 2017-03-24 09:43:51 -04:00
Francis Lachapelle 7065c4f765 Preparation for release 3.2.8 2017-03-24 09:42:33 -04:00
Francis Lachapelle 2c8d1d0a26 (i18n) Update translations 2017-03-24 09:32:46 -04:00
InverseBot dab48bfc60 (js/css) Update generated files 2017-03-24 01:24:52 -04:00
Francis Lachapelle b0cc012849 (css,js) Update md to v1.1.3-master-e3f9772 2017-03-23 16:11:32 -04:00
Francis Lachapelle 1d028e4cf5 Expose default value SOGoMailAddOutgoingAddresses
Fixes #4064
2017-03-23 15:42:05 -04:00
Francis Lachapelle 4dcc1af46a (js) Improve recurrence editor 2017-03-23 14:01:28 -04:00
Francis Lachapelle c57f42b44b (js) Fix possible undefined variable 2017-03-23 13:58:34 -04:00
Francis Lachapelle 736921bdf7 (js) Fix display of category colors of components 2017-03-23 13:55:14 -04:00
Francis Lachapelle 0cc7c6be3d (js) Hide Copy/Move menu options with a single AB 2017-03-23 13:07:07 -04:00
Francis Lachapelle b7bc59d599 Enable Save btn after deleting attribute from card
Fixes #4095
2017-03-23 12:48:17 -04:00
InverseBot 2f92484064 (js/css) Update generated files 2017-03-23 01:24:54 -04:00
Francis Lachapelle b463fd4eda (js) Drop sgTransformOnBlur directive
The md-chips component has now a functional "md-add-on-blur" functionality.

Fixes #3944
2017-03-22 15:35:05 -04:00
Francis Lachapelle 75aaef0f3d (js) Restrict special mailboxes to the top level
Fixes #6963
2017-03-22 14:53:07 -04:00
Francis Lachapelle e7a06c42a4 (js) Fix sanitisation of flags in Sieve filters
Fixes #4087
2017-03-22 13:26:43 -04:00
Francis Lachapelle 5ff8463fba (js) Split string when pasting multiple addresses
Fixes #4097
2017-03-22 11:58:05 -04:00
Francis Lachapelle bc8146ef5d Remove debugging output 2017-01-29 18:02:44 -05:00
Ludovic Marcotte b25480f228 Updated NEWS 2017-03-18 15:37:45 -04:00
Ludovic Marcotte 585cda36d1 (fix) fix opacity in freebusy over EAS 2017-03-18 15:34:56 -04:00
Ludovic Marcotte b6d9c3e8e0 (fix) remove old code conflicting with #3905 2017-03-15 10:39:22 -04:00
Ludovic Marcotte ce8f2e9481 (fix) fixed task sorting on multiple categories 2017-03-14 14:18:53 -04:00
InverseBot cb532de83a (js/css) Update generated files 2017-03-14 09:09:24 -04:00
Francis Lachapelle 1aebad854b (js) Add missing variable declaration 2017-03-10 15:05:46 -05:00
Francis Lachapelle 9f6bc8a749 (js) Fix freebusy coverage of newly created event 2017-03-10 14:50:27 -05:00
Francis Lachapelle d24ff75ecf (js) Fix button to remove an attendee 2017-03-10 14:49:32 -05:00
Francis Lachapelle f60ffa923e (js) Display the attendees editor automatically 2017-03-10 14:48:53 -05:00
Francis Lachapelle 19512a85d2 (html) Caption for freebusy data of attendees 2017-03-10 14:43:02 -05:00
Francis Lachapelle baa6d39e28 (css) Generated no-animation.css 2017-03-10 06:36:14 -05:00
Ludovic Marcotte 5d9673415a (fix) don't abort on unhandled requests 2017-03-09 13:58:05 -05:00
Francis Lachapelle 50f25b0597 (i18n) Update translations 2017-03-09 12:19:12 -05:00
Francis Lachapelle 0a0f8a8d89 (css) Custom CSS for IE 2017-03-09 12:16:51 -05:00
Francis Lachapelle 489e35158c (css) Restore lost .md-fab-overlap-bottom class 2017-03-09 09:13:03 -05:00
InverseBot 11d9df6e6a (js/css) Update generated files 2017-03-09 01:26:19 -05:00
Francis Lachapelle e5dc76cc19 (js) Check alarms only if Calendar is accessible
Fixes #4067
2017-03-08 16:15:15 -05:00
Francis Lachapelle ab7ec63f4b Fix typo in Scheduler
Fixes #4072
2017-03-08 16:05:03 -05:00
Francis Lachapelle 1964fdebcb (html) Improve display of vacation message in pref 2017-03-08 16:05:03 -05:00
InverseBot 5b6807b78c (js/css) Update generated files 2017-03-08 09:42:14 -05:00
Ludovic Marcotte 9603971c1f (fix) wrong var type declaration 2017-03-08 09:31:19 -05:00
Ludovic Marcotte 4ae8961947 (fix) handle when mail starts with Bcc header (fixes #4073) 2017-03-08 08:42:56 -05:00
InverseBot 0ffbc13376 (js/css) Update generated files 2017-03-08 01:57:09 -05:00
Francis Lachapelle a02fa44dc7 (js) Fix SCAYT automatic language selection 2017-03-07 14:23:42 -05:00
Francis Lachapelle 682f699e2f Fix Welsh's locale 2017-03-07 14:20:51 -05:00
Ludovic Marcotte f3b098da75 Updated NEWS 2017-03-07 10:48:20 -05:00
Ludovic Marcotte 6a963bf84b (fix) remove attendees that have the same identity of the organizer (fixes #3905) 2017-03-07 10:45:44 -05:00
Francis Lachapelle 270ff1bd29 (js) Fix saving draft outside Mail module
Fixes #4071
2017-03-07 10:26:10 -05:00
InverseBot 74c2926bca (js/css) Update generated files 2017-03-04 01:34:40 -05:00
Francis Lachapelle 75aa6e90a2 (js) Fix handling of attachments in mail editor
Fixes #4058, #4063
2017-03-03 15:36:52 -05:00
Francis Lachapelle 3c35c16bf3 (html) Display year in day and week views 2017-03-03 15:01:00 -05:00
Ludovic Marcotte e95e8e9eac Updated NEWS 2017-03-03 14:15:27 -05:00
Ludovic Marcotte 588ec2b005 (fix) fixed handling of exdates and proper intersection for fbinfo (fixes #4051) 2017-03-03 14:13:25 -05:00
Francis Lachapelle 0627c2f58b (html) Constrain reminder to a positive number 2017-03-03 12:06:33 -05:00
Francis Lachapelle f6ed816243 (html) Constrain reminder to a positive number 2017-03-03 12:05:34 -05:00
Francis Lachapelle 25430a8128 Fix handling of contact organizations
Fixes #4028
2017-03-03 10:35:50 -05:00
Ludovic Marcotte 79a0d5e133 (fix) handle broken CalDAV clients sending bogus SENT-BY (fixes #3992) 2017-03-03 08:47:59 -05:00
InverseBot 018b7b7ab9 (js/css) Update generated files 2017-03-03 01:24:59 -05:00
Francis Lachapelle c8539dffa1 (js) Limit http error interceptor to JSON request 2017-03-02 15:48:31 -05:00
InverseBot c995c6e9d7 (js/css) Update generated files 2017-03-02 01:27:34 -05:00
Francis Lachapelle 8322d318aa Expose default value of SOGoMailAutoSave
Fixes #4053
2017-03-01 15:14:09 -05:00
Ludovic Marcotte 4d88eab13b Updated NEWS 2017-03-01 11:36:15 -05:00
Francis Lachapelle a3d7ae3a6b (js) Improve CAS handling 2017-03-01 11:15:25 -05:00
Ludovic Marcotte a29ced853a (js/css) Update generated files 2017-03-01 11:00:17 -05:00
Ludovic Marcotte 5047aed6ed (fix) more CAS fixes 2017-03-01 10:51:01 -05:00
Ludovic Marcotte 3c46a6ef14 (js/css) Update generated files 2017-03-01 09:49:36 -05:00
Ludovic Marcotte af3a35169a (fix) first pass at CAS XHR issue 2017-03-01 09:37:37 -05:00
InverseBot 6b471994ef (js/css) Update generated files 2017-03-01 01:23:28 -05:00
Francis Lachapelle 23ff62a9e0 (js) Improve event editor
- fixed form validity check;
- fixed alarm restoration after a reset;
- fixed recurrence rules check.
2017-02-28 16:13:58 -05:00
Francis Lachapelle 2a820bd780 (css) Improve display of event editor 2017-02-28 08:36:27 -05:00
InverseBot 125178e526 (js/css) Update generated files 2017-02-28 01:23:07 -05:00
Francis Lachapelle e1979976a6 (js) Month day(s) of monthly repeat must be set 2017-02-27 16:04:49 -05:00
Francis Lachapelle d87cf6980a (css) Improve display of recurrence editor 2017-02-27 16:03:45 -05:00
Francis Lachapelle dfce966e79 (js) Calendar week days must be set to save prefs 2017-02-27 12:55:15 -05:00
Francis Lachapelle 4002650748 (js) Expose model validity in sg-toggle-grid 2017-02-27 10:48:40 -05:00
InverseBot 0fa8cbf9cb (js/css) Update generated files 2017-02-23 01:24:05 -05:00
Francis Lachapelle 7a4dbcb364 (js) Update children paths when renaming a mailbox
Fixes #4046
2017-02-22 23:07:26 -05:00
Ludovic Marcotte 784503bdbc (fix) minor fixes in tools 2017-02-22 11:00:01 -05:00
Ludovic Marcotte 91b32faac2 Updated NEWS 2017-02-21 10:14:58 -05:00
Ludovic Marcotte f24d9ae389 (fix) safety checks, fixed remove ALL and added add ALL 2017-02-21 10:12:55 -05:00
Ludovic Marcotte b501014935 (feat) new sogo-tool manage-acl feature to get/add/remove ACLs from GCS folders 2017-02-20 18:57:46 -05:00
Ludovic Marcotte cc52e82524 (feat) added delete capability to sogo-tool checkup 2017-02-20 13:37:23 -05:00
Ludovic Marcotte fe42180bc0 (fix) set the memcache retry timeout to 5 seconds 2017-02-20 10:35:08 -05:00
Ludovic Marcotte 7f67e90c53 (fix) enable tcp_nodelay for memcache 2017-02-20 10:34:54 -05:00
InverseBot bf001b1af6 (js/css) Update generated files 2017-02-20 01:22:37 -05:00
Francis Lachapelle 3c65973cd5 (css) Hide fab button when printing
Fixes #4038
2017-02-19 21:57:27 -05:00
Francis Lachapelle 48b2008da4 (js) Localize mailbox names everywhere
Fixes #4041
2017-02-19 21:13:44 -05:00
InverseBot fd13fd632c (js/css) Update generated files 2017-02-18 01:21:42 -05:00
Francis Lachapelle b1e8f30138 (js) Localized inbox label
Fixes #4040
2017-02-17 21:22:10 -05:00
Ludovic Marcotte fc68709956 Updated NEWS 2017-02-17 15:19:37 -05:00
Francis Lachapelle 06238a39b1 (js) Fix fcn call when removing contact category
Fixes #4039
2017-02-17 11:01:42 -05:00
Francis Lachapelle 9f84162c5d (css) Fix ACL editor in Admin module for Safari
Fixes #4036
2017-02-15 23:11:34 -05:00
InverseBot 6ffc9a3552 (js/css) Update generated files 2017-02-15 01:29:55 -05:00
Ludovic Marcotte 3894d6f9fa Release preparation 2017-02-14 08:38:39 -05:00
InverseBot 07720563b9 (js/css) Update generated files 2017-02-14 01:16:42 -05:00
Francis Lachapelle 5ceafa5005 (js) Localize mail, phone, url and address types
Fixes #4030
2017-02-13 22:52:03 -05:00
Ludovic Marcotte 24da483e2a Updated NEWS 2017-02-09 14:42:42 -05:00
Ludovic Marcotte 9434e3882e (feat) new sogo-tool checkup command to make sure user's data is sane 2017-02-09 14:39:24 -05:00
Ludovic Marcotte 7d1dd4ec76 Updated NEWS 2017-02-09 08:57:56 -05:00
Ludovic Marcotte 54eedb3363 (fix) moved bcc handling code to the generic mail sending method 2017-02-09 08:56:02 -05:00
InverseBot e9ea104a94 (js/css) Update generated files 2017-02-09 01:29:10 -05:00
InverseBot 99277421a1 (js/css) Update generated files 2017-02-08 01:27:36 -05:00
Ludovic Marcotte 3d5c0be441 Updated NEWS 2017-02-03 15:27:39 -05:00
Ludovic Marcotte dd8cccdafc (fix) correctly handle Canceled appointments 2017-02-03 15:24:42 -05:00
InverseBot dcfed38fc7 (js/css) Update generated files 2017-02-03 01:25:57 -05:00
InverseBot b58ec19625 (js/css) Update generated files 2017-02-02 01:24:16 -05:00
Francis Lachapelle d90533399d (css) Keep the fab button visible 2017-02-01 21:33:17 -05:00
Ludovic Marcotte 4db1f8185a Updated NEWS 2017-02-01 13:06:03 -05:00
Ludovic Marcotte 50d8975f9d (fix) improve EAS parameters parsing (fixes #4003) 2017-02-01 13:03:27 -05:00
Francis Lachapelle b412788e39 Make sure to refer to filenames when executing zip
Fixes #4015
2017-02-01 11:56:44 -05:00
Ludovic Marcotte 15b277fa8e (fix) cache sogo_folder_info records and avoid phantom subscriptions (fixes #4010) 2017-01-31 15:59:58 -05:00
InverseBot d159b191a6 (js/css) Update generated files 2017-01-31 01:12:42 -05:00
Francis Lachapelle 539a6c3beb Fix public URL with special characters
Fixes #3993
2017-01-30 21:56:33 -05:00
Francis Lachapelle abccdd304f (js) Ignore mouse events in scrollbars of Month
Firefox is bubbling the mouse down event on scrollbars so it has to be
ignored for proper drag'n'drop.

Fixes #3990.
2017-01-30 15:52:07 -05:00
Francis Lachapelle 4143a23afd Add Hebrew translation (cont'd) 2017-01-30 07:51:36 -05:00
Francis Lachapelle a020286780 Merge pull request #232 from rfrei/patch-1
Allow write to multiple contacts using 'to', 'cc' or 'bcc'.

Fixes #3548.
2017-01-30 07:46:54 -05:00
Steffen Müller 1b264ef6ba Change Strings according to RFC 5322
correction: for translations the strings in English.lproj should better be equal
2017-01-28 17:53:14 +01:00
Steffen Müller ef4e311a5a Change Strings according to RFC 5322 2017-01-28 17:53:05 +01:00
Steffen Müller 1d8caa4297 Change Strings according to RFC 5322 2017-01-28 17:22:14 +01:00
InverseBot 0500499d91 (js/css) Update generated files 2017-01-28 01:10:29 -05:00
Francis Lachapelle d289a441bb Fix condition when enabling Vacation message 2017-01-27 15:57:43 -05:00
Francis Lachapelle fcfbc50139 Add Hebrew translation (cont'd) 2017-01-27 12:58:31 -05:00
Francis Lachapelle 88bc1294cd (js) Fix saving the preferences with Mail disabled 2017-01-27 12:40:36 -05:00
Francis Lachapelle ac127a375f Improve ACLs handling of inactive users (cont'd) 2017-01-27 12:22:22 -05:00
Steffen Müller f90b2efadb simpler version 2017-01-27 16:52:58 +01:00
Steffen Müller c9a50aa057 write using 'to', 'cc' or 'bcc' with string parameter
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-27 16:41:34 +01:00
Steffen Müller 621adb38c2 write using 'to', 'cc' or 'bcc' with string parameter
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-27 16:37:13 +01:00
InverseBot 872afaec32 (js/css) Update generated files 2017-01-27 01:10:15 -05:00
Francis Lachapelle 892e6d6eb2 Add Hebrew translation 2017-01-26 21:40:52 -05:00
Steffen Müller ed62670a1a write using 'to', 'cc' or 'bcc'
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-26 19:27:13 +01:00
Francis Lachapelle 7a6df34cb6 Update ChangeLog 2017-01-26 13:18:17 -05:00
Francis Lachapelle 556460982d Preparation for release 3.2.6a 2017-01-26 13:17:52 -05:00
Francis Lachapelle 2beb3dca6d (js/css) Update generated files 2017-01-26 13:16:19 -05:00
Francis Lachapelle d14b0b0b5e (js) Improve ACLs handling of inactive users 2017-01-26 12:48:21 -05:00
Steffen Müller 8efd01d55e write using 'to', 'cc' or 'bcc'
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-26 18:29:07 +01:00
Francis Lachapelle 831c1bc980 Revert "(fix) properly honor "include in freebusy"
This reverts commit eed5679068.
2017-01-26 11:52:58 -05:00
Francis Lachapelle d277f2fe0f Update ChangeLog 2017-01-23 14:58:02 -05:00
Francis Lachapelle 0b9ca225d0 (css) Update default theme 2017-01-23 14:58:02 -05:00
Francis Lachapelle 04c256ab6c Preparation for release 3.2.6 2017-01-23 14:57:47 -05:00
InverseBot 3cbeba32d9 (js/css) Update generated files 2017-01-24 01:15:53 -05:00
Francis Lachapelle 1825b167dc (css,js) Update md to v1.1.1-master-2c9a5cc 2017-01-23 09:55:44 -05:00
Francis Lachapelle 214ce5ef86 (i18n) Update translations 2017-01-23 09:50:35 -05:00
Ludovic Marcotte 927f0c3220 Updated NEWS 2017-01-23 08:55:33 -05:00
Ludovic Marcotte 227cf582d9 (fix) touch objects when server-side changes occured 2017-01-23 08:53:41 -05:00
InverseBot 8cdc435945 (js/css) Update generated files 2017-01-21 01:28:13 -05:00
Francis Lachapelle 3efe0e8098 Add support for date extension of Sieve
Fixes #1530, #1949
2017-01-20 11:08:24 -05:00
Ludovic Marcotte d38d42b83a (fix) use login in domain 2017-01-20 09:25:02 -05:00
InverseBot 1f3a89b984 (js/css) Update generated files 2017-01-20 01:27:56 -05:00
Francis Lachapelle 0dea9c226d Allow to select multiple files when uploading
Fixes #3999
2017-01-19 15:41:21 -05:00
Francis Lachapelle db1cc24c20 (css) Improve display of HTML CKEditor 2017-01-19 14:47:11 -05:00
Francis Lachapelle d7d88e2620 (js) Compose new message in a popup window 2017-01-19 12:23:55 -05:00
Francis Lachapelle 4fca484ed0 Improve error handling in SOGoWebAppointmentFolder 2017-01-19 10:31:03 -05:00
Francis Lachapelle fcb79dc14b Improve error handling in MSExchangeFreeBusy class 2017-01-19 10:17:17 -05:00
Francis Lachapelle 41dbb88b64 (js) Expandable mail editor
Added "autogrow" plugin for CKEditor.
2017-01-19 07:05:52 -05:00
InverseBot bb97b57ad7 (js/css) Update generated files 2017-01-19 01:28:13 -05:00
Ludovic Marcotte 5300d4185d (fix) improve doc around SOGoTimeZone (fixes #3995) 2017-01-18 16:17:12 -05:00
Francis Lachapelle 26b69d25ee (js) Fix opening message in popup window 2017-01-18 15:03:29 -05:00
Ludovic Marcotte a3c056ea84 (fix) deep-search for text/calendar parts 2017-01-17 15:12:29 -05:00
Ludovic Marcotte e4b2539b04 (fix) strip attendees with no email and don't send IMIP when it's Outlook the EAS client 2017-01-17 12:40:41 -05:00
Francis Lachapelle fcb6542d06 (i18n) Update translations 2017-01-17 11:47:43 -05:00
Francis Lachapelle 174fcd5c31 (i18n) Update translations 2017-01-17 08:53:52 -05:00
InverseBot 2f6c5148aa (js/css) Update generated files 2017-01-17 01:30:41 -05:00
Francis Lachapelle 936b21b8c0 (css) Fix glitches in Month view with Firefox 2017-01-16 16:30:24 -05:00
Francis Lachapelle 5f2a6c53c4 (js) Fix pasting images in CKEditor
Fixes #3986
2017-01-16 15:31:12 -05:00
Francis Lachapelle ba12c14a1d (js) Update CKEditor to version 4.6.2
- Add Upload Image plugin

Fixes #3986
2017-01-13 16:11:10 -05:00
Ludovic Marcotte 4158f7555e Updated NEWS 2017-01-13 13:19:43 -05:00
Ludovic Marcotte 6e0f5b2254 (fix) return if not content is there, to avoid random crash 2017-01-13 13:16:01 -05:00
Francis Lachapelle 4a21a02f98 Fix rendering of forwarded HTML message with img
Fixes #3981 (cont'd)
2017-01-13 12:23:38 -05:00
Ludovic Marcotte 9d7d2575d3 (ix) remove alarms in IMIP responses (fixes #3925) 2017-01-12 15:23:09 -05:00
InverseBot 905859053c (js/css) Update generated files 2017-01-12 01:31:09 -05:00
Francis Lachapelle e5d0b0b0ca Fix rendering of forwarded HTML message with img
Fixes #3981 (partially)
2017-01-11 16:08:56 -05:00
Francis Lachapelle 589827a414 (html) Show locale codes beside language names 2017-01-11 14:20:43 -05:00
Francis Lachapelle 42ee981613 (js) Update Angular to branch 1.6.x 2017-01-11 14:20:43 -05:00
Francis Lachapelle 5985262e0f Improve WebDAV Python lib for integration tests 2017-01-11 14:20:42 -05:00
Francis Lachapelle c36fcd2902 Improve debugging output of recurrence calculator 2017-01-11 14:20:42 -05:00
Francis Lachapelle bce09f413f Update NEWS file 2017-01-11 14:20:42 -05:00
Francis Lachapelle 9477c1af16 (html) Precise EAS beside "Synchronize" option 2017-01-11 14:20:42 -05:00
InverseBot 8011d9093e (js/css) Update generated files 2017-01-11 01:26:52 -05:00
Francis Lachapelle 37334db0e3 Update ChangeLog 2017-01-10 09:42:57 -05:00
Francis Lachapelle 6637bde56d Preparation for release 3.2.5 2017-01-10 09:42:09 -05:00
Francis Lachapelle e27efc4d3a (css) Update default theme 2017-01-10 09:37:05 -05:00
Francis Lachapelle ff7b9a3725 (js/css) Update generated files 2017-01-10 09:33:43 -05:00
Francis Lachapelle 36c7ffcc3c (css,js) Update md to v1.1.1-master-64b2621 2017-01-10 09:16:04 -05:00
InverseBot 3912d2ab3e (js/css) Update generated files 2017-01-10 02:12:03 -05:00
Ludovic Marcotte 5e775ea4ce (fix) some more memory info 2017-01-09 16:09:09 -05:00
Ludovic Marcotte 841fdb96cc (fix) be a bit more verbose about memory usage 2017-01-09 16:03:32 -05:00
Francis Lachapelle 51ff746595 (js) Update CKEditor to version 4.6.1 2017-01-06 20:49:42 -05:00
Francis Lachapelle ef1f5a948f (i18n) Update translations 2017-01-06 20:34:37 -05:00
Francis Lachapelle 3560f0486e (js) Fix hotkeys with an active dialog in Mailer
Fixes #3983
2017-01-06 18:26:12 -05:00
Francis Lachapelle 327ebf00a4 Fix public URLs to Calendars
Fixes #3974
2017-01-06 16:49:00 -05:00
InverseBot abb1e1b447 (js/css) Update generated files 2017-01-07 01:28:44 -05:00
Francis Lachapelle 818233535f Improve error messages around draft attachments
(cont'd)
2017-01-06 16:17:05 -05:00
Francis Lachapelle 65e3fe978c Minor code cleanup 2017-01-06 16:15:26 -05:00
Francis Lachapelle 0216f19e55 Improve Installation Guide 2017-01-06 16:14:44 -05:00
Francis Lachapelle 8404de758b Improve error messages around draft attachments 2017-01-06 16:12:42 -05:00
Francis Lachapelle 5ec7ad54bb Fix error handling when draft is too big 2017-01-06 15:45:30 -05:00
Ludovic Marcotte be8e1373ea Updated NEWS 2017-01-06 16:01:52 -05:00
Ludovic Marcotte 9fbc84158a (fix) handle sha512-crypt with rounds 2017-01-06 15:52:19 -05:00
Ludovic Marcotte 071c1032c1 Updated NEWS 2017-01-06 14:34:43 -05:00
Ludovic Marcotte af8baf41cb (fix) correctly handle all identities during IMIP status update 2017-01-06 14:32:45 -05:00
Ludovic Marcotte 0b7ddf7ca4 (fix) small optimization over previous commit 2017-01-06 14:29:41 -05:00
Ludovic Marcotte 942ddcabe4 (fix) handle all identities during IMIP REPLY processing 2017-01-06 14:23:52 -05:00
Ludovic Marcotte bdd8254e02 (fix) make sure we compare the organizer's email only 2017-01-06 11:03:59 -05:00
Ludovic Marcotte ce0575517d (fix) make sure to bump LAST-MODIFIED to trigger all auto-scheduling code 2017-01-06 09:54:02 -05:00
Francis Lachapelle ea7934a73c Fix saving of inactive calendars
Fixes #3862, #3980
2017-01-06 06:42:12 -05:00
InverseBot 02fc147624 (js/css) Update generated files 2017-01-06 02:11:11 -05:00
Francis Lachapelle 02a1ad48fc (js) Fix computation of week number
Fixes #3973, 3976
2017-01-05 12:00:55 -05:00
Ludovic Marcotte e7e1283fb3 (fix) disabled bias computation for now 2017-01-05 09:27:16 -05:00
InverseBot d5e04be1df (js/css) Update generated files 2017-01-01 01:20:37 -05:00
Ludovic Marcotte e2ec8af0db Updated NEWS 2016-12-30 12:29:09 -05:00
Ludovic Marcotte 477c06a7ff (fix) fix events in floating time during CalDAV's PUT operation (fixes #2865) 2016-12-30 12:26:31 -05:00
Ludovic Marcotte 479b534857 (fix) properly save email alarms in the db (fixes #3949) 2016-12-30 10:31:29 -05:00
Ludovic Marcotte f6bcf26793 Updated NEWS 2016-12-30 10:00:58 -05:00
Ludovic Marcotte cdf6aaa53e (fix) provide correct error response to EAS client when sending big mails (fixes #3956) 2016-12-30 09:58:51 -05:00
Ludovic Marcotte 1a9b20519e Updated NEWS 2016-12-29 16:23:07 -05:00
Ludovic Marcotte 4f211678e9 (fix) handle semicolon in value during LDIF import (fixes #1760) 2016-12-29 16:21:30 -05:00
Ludovic Marcotte e578787acd Updated NEWS 2016-12-29 14:37:04 -05:00
Ludovic Marcotte 239dffa391 (fix) handle URI in vCard photos (fixes #2683) 2016-12-29 14:35:06 -05:00
Ludovic Marcotte 6cd3d90410 Updated NEWS 2016-12-29 14:14:39 -05:00
Ludovic Marcotte 93dfbc5a94 (feat) added photo support for LDIF import (fixes #1084) 2016-12-29 14:12:45 -05:00
Ludovic Marcotte 896f57f634 Updated NEWS 2016-12-29 10:53:44 -05:00
Ludovic Marcotte f48ab310d6 (fix) add support for "other" addresses (fixes #3966) 2016-12-29 10:52:32 -05:00
Ludovic Marcotte 5bc21e4f53 (fix) avoid trying to parse empty request (fixes #3969) 2016-12-29 09:55:20 -05:00
Ludovic Marcotte 8296123650 Updated NEWS 2016-12-28 10:25:31 -05:00
Ludovic Marcotte 2cebee42b7 (feat) added new SOGoMaximumMessageSizeLimit config parameter (fixes #3510)
Conflicts:

	SoObjects/Mailer/SOGoDraftObject.m
2016-12-28 10:23:19 -05:00
Ludovic Marcotte 7c7440c988 Updated NEWS 2016-12-23 11:38:39 -05:00
Ludovic Marcotte eed5679068 (fix) properly honor "include in freebusy" (fixes #3354) 2016-12-23 11:36:44 -05:00
Ludovic Marcotte f1dbb88303 Updated NEWS 2016-12-23 10:22:07 -05:00
Ludovic Marcotte 9cb6772ae8 (fix) do not decode from hex the event's UID (fixes #3965) 2016-12-23 10:19:46 -05:00
Ludovic Marcotte dceab8fd2a Updated NEWS 2016-12-23 10:06:15 -05:00
Ludovic Marcotte 7197b7eb41 (fix) handle delegation scenario with no SENT-BY set (fixes #3368) 2016-12-23 10:04:43 -05:00
InverseBot 18b502c39c (js/css) Update generated files 2016-12-23 02:10:39 -05:00
Ludovic Marcotte 94fc5d17db (fix) also use the filter when doing DN lookups (fixes #2253) 2016-12-22 14:26:27 -05:00
Ludovic Marcotte 8c075d2e1b (fix) comment out vars too 2016-12-22 09:41:39 -05:00
Ludovic Marcotte 278aeef864 (fix) disabled IMIP force sending for Lightning (fixes #3274) 2016-12-22 08:55:12 -05:00
Ludovic Marcotte ef69344a59 Updated NEWS 2016-12-21 11:45:41 -05:00
Ludovic Marcotte 457fccd5ac (fix) append .ics extension if not present when importing events (fixes #2308) 2016-12-21 11:43:08 -05:00
Ludovic Marcotte 1da36a3ef9 (fix) always force save events creation over EAS (fixes #3958) 2016-12-21 10:47:33 -05:00
Francis Lachapelle 7327ec21b2 Avoid duplicate emails in LDAP-based address book
Fixes #3941
2016-12-21 10:37:04 -05:00
Ludovic Marcotte 94c522ea5c Updated NEWS 2016-12-21 08:50:38 -05:00
Ludovic Marcotte 5c0229466e (feat) handle alarms for tasks (fixes #3964) 2016-12-21 08:49:05 -05:00
Ludovic Marcotte eb6d234c4b Updated NEWS 2016-12-20 13:17:19 -05:00
Ludovic Marcotte 06903f8376 (fix) use the source's domain if none is defined (fixes #3523) 2016-12-20 13:15:15 -05:00
Francis Lachapelle 596c4bb4c2 (js) Fix attached links in task viewer
Fixes #3963
2016-12-20 10:44:43 -05:00
Ludovic Marcotte 3d16283d3c (fix) avoid double encoding (fixes #3960) 2016-12-20 08:56:13 -05:00
InverseBot 31d2db51ad (js/css) Update generated files 2016-12-20 01:24:11 -05:00
Ludovic Marcotte abd0c0a744 (fix) sage-guard against empty rrule 2016-12-19 15:01:31 -05:00
Francis Lachapelle 1375237697 (js) Don't allow to create a list in a remote AB 2016-12-19 12:07:17 -05:00
Francis Lachapelle 4c78d81bf7 Formatting & Comments 2016-12-19 11:15:35 -05:00
Francis Lachapelle 2e9168080c (js) Fix freebusy initialization in event editor 2016-12-19 11:05:48 -05:00
Francis Lachapelle 1eb378c956 (js) Fix display of auto-reply (vacation) message
Fixes #3940
2016-12-19 10:25:04 -05:00
Francis Lachapelle e739ed46a3 (js) Fix saving monthly BYDAY recurrence
Fixes #3948
2016-12-19 09:51:09 -05:00
Francis Lachapelle 93f559a0df Remove unnecessary div in UIxTopnavToolbar.wox 2016-12-19 09:46:58 -05:00
InverseBot 13a4398c4d (js/css) Update generated files 2016-12-17 01:24:00 -05:00
Ludovic Marcotte 462d274497 Updated NEWS 2016-12-16 15:53:12 -05:00
Ludovic Marcotte ab1c699bc7 (feat) better support for RFC 6638 (schedule-agent) (fixes #2599) 2016-12-16 15:51:19 -05:00
Ludovic Marcotte 9882052e81 Updated NEWS 2016-12-16 10:12:40 -05:00
Ludovic Marcotte 3adbef5aa4 (fix) 30 mins offset in FB 2016-12-16 10:08:04 -05:00
Ludovic Marcotte 5ecf917e6b (fix) return a 404 for public user 2016-12-16 09:07:55 -05:00
InverseBot a02642cad9 (js/css) Update generated files 2016-12-16 01:09:03 -05:00
Ludovic Marcotte 92ba421dd1 Updated NEWS 2016-12-15 14:24:08 -05:00
Ludovic Marcotte ea940e645e (fix) return login page for unknown users (fixes #2135) 2016-12-15 14:22:26 -05:00
Francis Lachapelle 651c0fdf14 Load photos of LDAP-based address books in listing
Fixes #3942
2016-12-15 10:19:47 -05:00
InverseBot 15a3bf48d9 (js/css) Update generated files 2016-12-15 01:22:53 -05:00
Ludovic Marcotte 8493701408 Updated NEWS 2016-12-14 21:22:45 -05:00
Ludovic Marcotte f0085ef43e (fix) correctly block if fail count is within interval (fixes #2850) 2016-12-14 21:20:29 -05:00
Francis Lachapelle e0108088ee (js) Rename buttons of alarm toast
Fixes #3945
2016-12-14 16:39:21 -05:00
Francis Lachapelle 5591b9d423 (js) Switch on "remember username" when necessary 2016-12-14 16:33:21 -05:00
Ludovic Marcotte ef96c21334 Updated NEWS 2016-12-14 13:46:27 -05:00
Ludovic Marcotte d8eae96d63 (fix) properly skip folders we don't want (fixes #3943) 2016-12-14 13:42:22 -05:00
InverseBot f6acc3e984 (js/css) Update generated files 2016-12-11 01:19:01 -05:00
Ludovic Marcotte 340ddf0ae6 (fix) make sure we safely escape all chars 2016-12-09 10:45:44 -05:00
Ludovic Marcotte b0fcaeef86 (fix) removed old code 2016-12-09 10:32:42 -05:00
Ludovic Marcotte ec19a1290d (fix) use the organizer's alarm by default when accepting IMIP messages (fixes #3934) 2016-12-09 09:47:48 -05:00
InverseBot 384f1cb53f (js/css) Update generated files 2016-12-09 01:17:34 -05:00
Francis Lachapelle d0e0d5300a (js) Fix ordering of calendars
Fixes #3931
2016-12-08 10:17:25 -05:00
InverseBot 4b2b3693c5 (js/css) Update generated files 2016-12-08 01:18:39 -05:00
Francis Lachapelle 011fae8a65 Download attachments of a message as a zip archive 2016-12-07 14:38:33 -05:00
Ludovic Marcotte 2a2ebd553e (test) handle sanitization before passing data to libxml 2016-12-06 14:05:27 -05:00
Francis Lachapelle 0038e4bc60 (js) Disable HTML entities in CKEditor 2016-12-06 10:08:02 -05:00
InverseBot e053f12e78 (js/css) Update generated files 2016-12-06 01:17:41 -05:00
Francis Lachapelle c663f7ab4c Prevent using localhost on auxiliary IMAP accounts 2016-12-05 16:12:16 -05:00
Ludovic Marcotte 68ddcd7045 (fix) prevent using localhost on additional IMAP accounts 2016-12-05 14:51:33 -05:00
InverseBot ffd69337f6 (js/css) Update generated files 2016-12-03 02:04:11 -05:00
Francis Lachapelle ba5bd65ea3 Fix support for SOGoSieveFolderEncoding defaults
Cont'd. Fixes #3904
2016-12-02 17:38:33 -05:00
Francis Lachapelle 6ce64a9a27 (js) Fix sorting after renaming an AddressBook 2016-12-02 14:48:59 -05:00
Ludovic Marcotte 41701cc94c (fix) properly set interval for monthly recurring events using EAS 2016-12-02 09:21:18 -05:00
Ludovic Marcotte 56d7f634a0 (fix) avoid compiler warning 2016-12-02 08:48:26 -05:00
InverseBot 80f67785c3 (js/css) Update generated files 2016-12-02 01:29:36 -05:00
Francis Lachapelle 29dfadfe75 (css) Update default theme 2016-12-01 17:47:29 -05:00
Francis Lachapelle fb743d6381 Update Developer's Guide 2016-12-01 16:01:45 -05:00
Francis Lachapelle 203dcf1d05 (js) Improve sgAvatarImage (cont'd) 2016-12-01 15:42:28 -05:00
Francis Lachapelle 0d95267fe5 Fix ACLs management of folders in Administration
The active (super) user was not able to add herself to the ACLs of a
different user because we were removing the active user from the users
search instead of removing the folder's owner.
2016-12-01 15:40:38 -05:00
Francis Lachapelle e997923c31 (html) Fix sidenav breakpoint in Admin module 2016-12-01 15:32:24 -05:00
Francis Lachapelle 277c6e901e Update ChangeLog 2016-12-01 12:02:23 -05:00
Francis Lachapelle 2c24901803 (js/css) Update generated files 2016-12-01 12:01:50 -05:00
Francis Lachapelle 8f90aa96fe (css,js) Update md to v1.1.1-master-b8357dc 2016-12-01 12:00:00 -05:00
Francis Lachapelle ee5b60c544 Preparation for release 3.2.4 2016-12-01 11:59:16 -05:00
Francis Lachapelle d2b94eba09 (js) Fix detection of session expiration 2016-12-01 11:56:07 -05:00
Francis Lachapelle c9467e1ce3 Validate custom subject for vacation auto-reply 2016-12-01 11:21:59 -05:00
Francis Lachapelle b4e9b7b60c (css) Fix sidenav background color of Preferences 2016-12-01 11:14:38 -05:00
Francis Lachapelle 66710f1b17 (i18n) Update translations 2016-12-01 11:07:28 -05:00
Francis Lachapelle a61ea24cdb (obj-c) Indentation 2016-12-01 10:28:26 -05:00
Francis Lachapelle 3e448d2c2c New sogo-tool cleanup user feature (cont'd) 2016-12-01 10:27:22 -05:00
Ludovic Marcotte 9aa00d049d Updated NEWS 2016-12-01 09:42:03 -05:00
Ludovic Marcotte fdea54f5e7 (fix) properly escape all GAL responses (fixes #3923) 2016-12-01 09:40:24 -05:00
InverseBot 3c098ceca5 (js/css) Update generated files 2016-12-01 01:18:40 -05:00
Francis Lachapelle f7dd835f92 Fix mail attribute when importing an LDIF file
Fixes #3878
2016-11-30 16:06:09 -05:00
Francis Lachapelle 7705c11cf7 New sogo-tool cleanup user feature 2016-11-30 15:32:29 -05:00
Francis Lachapelle 52cdb71d1f Add sort by start date for the tasks list
Fixes #3840
2016-11-30 12:13:48 -05:00
Francis Lachapelle a1746cd386 (css) Fix display of tabs with oversized content 2016-11-30 12:09:11 -05:00
InverseBot cd08ab81f1 (js/css) Update generated files 2016-11-30 02:47:47 -05:00
Francis Lachapelle d293fe79ed Add handling of BYSETPOS for BYDAY in repeat rule 2016-11-29 17:47:14 -05:00
Francis Lachapelle 6f732ba535 Fix MSExchangeFreeBusySOAPRequest.wod 2016-11-29 16:14:42 -05:00
Francis Lachapelle b27c868271 Fix freebusy data fetching of MS Exchange contacts 2016-11-29 15:48:15 -05:00
InverseBot e0b0a1d783 (js/css) Update generated files 2016-11-29 03:13:53 -05:00
Francis Lachapelle e059a6043e (js) Fix possible cross-origin exception
When SOGo is launched from an external link, either using a different
"target" or using window.open(), the Mail composer could throw a
JavaScript exception when trying to save or send a message that would
completely stop the operation.

Fixes #3900
2016-11-28 15:36:03 -05:00
Francis Lachapelle e253f5735d (js) Don't test pristine state of Message composer 2016-11-28 11:45:09 -05:00
Francis Lachapelle 328d67ec3a Improve sort validation in Contacts module 2016-11-28 10:33:38 -05:00
Francis Lachapelle c3376a4ddf Fix some compilation warnings 2016-11-28 10:14:23 -05:00
Francis Lachapelle 220fb3d607 (js) Update alarms after dragging an event 2016-11-28 09:37:31 -05:00
InverseBot fb873fcae9 (js/css) Update generated files 2016-11-26 02:52:49 -05:00
Ludovic Marcotte d2e03386d2 (fix) use GMT + adjust bias when querying Exchange's FB info 2016-11-25 15:14:24 -05:00
Francis Lachapelle 35a3a8ef1d Update ChangeLog 2016-11-25 10:57:26 -05:00
Francis Lachapelle 309846c894 (js/css) Update generated files 2016-11-25 10:52:36 -05:00
Francis Lachapelle f84d0e5f30 Preparation for release 3.2.3 2016-11-25 10:45:07 -05:00
InverseBot 9bb22bd67a (js/css) Update generated files 2016-11-25 02:43:18 -05:00
Francis Lachapelle dc7cb6792a (js) Improve alarms dialog
Fixes #3909
2016-11-24 19:14:02 -05:00
Ludovic Marcotte a76f8dca04 Updated NEWS 2016-11-24 16:07:47 -05:00
Ludovic Marcotte 06e92bbde5 Updated NEWS 2016-11-24 15:54:34 -05:00
Ludovic Marcotte 022c4bac98 (fix) wrong check for delete permission 2016-11-24 15:49:10 -05:00
Ludovic Marcotte 0e82802082 (fix) also filter out recurrence-id 2016-11-24 15:43:37 -05:00
Francis Lachapelle 0a4fa9aada (css) Update default theme 2016-11-24 15:09:59 -05:00
Ludovic Marcotte 71ca4a7b47 (fix) don't check Dovecot conditions if we're using IMAP annotations 2016-11-24 11:39:05 -05:00
Francis Lachapelle 2878665af4 Merge pull request #227 from andryyy/patch-5
Update SOGoACLGermanModificationAdvisory.wox
2016-11-24 06:34:27 -05:00
Francis Lachapelle 9f5a6707bb Merge pull request #226 from andryyy/patch-4
Update SOGoACLGermanRemovalAdvisory.wox
2016-11-24 06:33:52 -05:00
InverseBot 0e07844108 (js/css) Update generated files 2016-11-24 03:11:27 -05:00
André Peters 7c9d8b19b9 Update SOGoACLGermanModificationAdvisory.wox
Fix umlauts in messages like "... Zugang zu seinem Order "Persönlicher Kalender".
2016-11-24 08:50:43 +01:00
André Peters 1f9ef6fea7 Update SOGoACLGermanRemovalAdvisory.wox
Fix umlauts in messages like "... Zugang zu seinem Order "Persönlicher Kalender".
2016-11-24 08:50:42 +01:00
Ludovic Marcotte 836fdb1722 (feat) added photo support for LDAP-based address books 2016-11-23 16:30:41 -05:00
Francis Lachapelle cb960fae02 Restore attributes of base64-encoded img tags
Fixes #3814
2016-11-23 14:57:24 -05:00
Francis Lachapelle b8df16cd8c Improve SOGoDefaults.plist to avoid warning 2016-11-23 14:52:10 -05:00
Francis Lachapelle 84e591cdb9 (js) Update CKEditor to version 4.6.0 2016-11-23 13:57:49 -05:00
1020 changed files with 53210 additions and 26583 deletions

No files matched your search

-2
View File
@@ -19,8 +19,6 @@ UI/WebServerResources/.bowerrc
UI/WebServerResources/.sass-cache/
UI/WebServerResources/bower_components/
UI/WebServerResources/css/
UI/WebServerResources/css/styles.css
UI/WebServerResources/css/styles.css.map
UI/WebServerResources/js/*.js
UI/WebServerResources/js/*.js.map
UI/WebServerResources/js/vendor/*.js
+22
View File
@@ -15,11 +15,13 @@ trans.es_ES = UI/MailerUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MailerUI/Basque.lproj/Localizable.strings
trans.fi = UI/MailerUI/Finnish.lproj/Localizable.strings
trans.fr = UI/MailerUI/French.lproj/Localizable.strings
trans.he = UI/MailerUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MailerUI/Croatian.lproj/Localizable.strings
trans.hu = UI/MailerUI/Hungarian.lproj/Localizable.strings
trans.is = UI/MailerUI/Icelandic.lproj/Localizable.strings
trans.it = UI/MailerUI/Italian.lproj/Localizable.strings
trans.lt = UI/MailerUI/Lithuanian.lproj/Localizable.strings
trans.lv = UI/MailerUI/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/MailerUI/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/MailerUI/Dutch.lproj/Localizable.strings
@@ -50,11 +52,13 @@ trans.es_ES = UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/PreferencesUI/Basque.lproj/Localizable.strings
trans.fi = UI/PreferencesUI/Finnish.lproj/Localizable.strings
trans.fr = UI/PreferencesUI/French.lproj/Localizable.strings
trans.he = UI/PreferencesUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/PreferencesUI/Croatian.lproj/Localizable.strings
trans.hu = UI/PreferencesUI/Hungarian.lproj/Localizable.strings
trans.is = UI/PreferencesUI/Icelandic.lproj/Localizable.strings
trans.it = UI/PreferencesUI/Italian.lproj/Localizable.strings
trans.lt = UI/PreferencesUI/Lithuanian.lproj/Localizable.strings
trans.lv = UI/PreferencesUI/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/PreferencesUI/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/PreferencesUI/Dutch.lproj/Localizable.strings
@@ -85,11 +89,13 @@ trans.es_ES = UI/Scheduler/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Scheduler/Basque.lproj/Localizable.strings
trans.fi = UI/Scheduler/Finnish.lproj/Localizable.strings
trans.fr = UI/Scheduler/French.lproj/Localizable.strings
trans.he = UI/Scheduler/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Scheduler/Croatian.lproj/Localizable.strings
trans.hu = UI/Scheduler/Hungarian.lproj/Localizable.strings
trans.is = UI/Scheduler/Icelandic.lproj/Localizable.strings
trans.it = UI/Scheduler/Italian.lproj/Localizable.strings
trans.lt = UI/Scheduler/Lithuanian.lproj/Localizable.strings
trans.lv = UI/Scheduler/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/Scheduler/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/Scheduler/Dutch.lproj/Localizable.strings
@@ -120,11 +126,13 @@ trans.es_ES = UI/Contacts/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Contacts/Basque.lproj/Localizable.strings
trans.fi = UI/Contacts/Finnish.lproj/Localizable.strings
trans.fr = UI/Contacts/French.lproj/Localizable.strings
trans.he = UI/Contacts/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Contacts/Croatian.lproj/Localizable.strings
trans.hu = UI/Contacts/Hungarian.lproj/Localizable.strings
trans.is = UI/Contacts/Icelandic.lproj/Localizable.strings
trans.it = UI/Contacts/Italian.lproj/Localizable.strings
trans.lt = UI/Contacts/Lithuanian.lproj/Localizable.strings
trans.lv = UI/Contacts/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/Contacts/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/Contacts/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/Contacts/Dutch.lproj/Localizable.strings
@@ -155,11 +163,13 @@ trans.es_ES = UI/MainUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MainUI/Basque.lproj/Localizable.strings
trans.fi = UI/MainUI/Finnish.lproj/Localizable.strings
trans.fr = UI/MainUI/French.lproj/Localizable.strings
trans.he = UI/MainUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MainUI/Croatian.lproj/Localizable.strings
trans.hu = UI/MainUI/Hungarian.lproj/Localizable.strings
trans.is = UI/MainUI/Icelandic.lproj/Localizable.strings
trans.it = UI/MainUI/Italian.lproj/Localizable.strings
trans.lt = UI/MainUI/Lithuanian.lproj/Localizable.strings
trans.lv = UI/MainUI/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/MainUI/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/MainUI/Dutch.lproj/Localizable.strings
@@ -190,11 +200,13 @@ trans.es_ES = UI/Common/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Common/Basque.lproj/Localizable.strings
trans.fi = UI/Common/Finnish.lproj/Localizable.strings
trans.fr = UI/Common/French.lproj/Localizable.strings
trans.he = UI/Common/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Common/Croatian.lproj/Localizable.strings
trans.hu = UI/Common/Hungarian.lproj/Localizable.strings
trans.is = UI/Common/Icelandic.lproj/Localizable.strings
trans.it = UI/Common/Italian.lproj/Localizable.strings
trans.lt = UI/Common/Lithuanian.lproj/Localizable.strings
trans.lv = UI/Common/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/Common/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/Common/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/Common/Dutch.lproj/Localizable.strings
@@ -225,11 +237,13 @@ trans.es_ES = UI/AdministrationUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/AdministrationUI/Basque.lproj/Localizable.strings
trans.fi = UI/AdministrationUI/Finnish.lproj/Localizable.strings
trans.fr = UI/AdministrationUI/French.lproj/Localizable.strings
trans.he = UI/AdministrationUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/AdministrationUI/Croatian.lproj/Localizable.strings
trans.hu = UI/AdministrationUI/Hungarian.lproj/Localizable.strings
trans.is = UI/AdministrationUI/Icelandic.lproj/Localizable.strings
trans.it = UI/AdministrationUI/Italian.lproj/Localizable.strings
trans.lt = UI/AdministrationUI/Lithuanian.lproj/Localizable.strings
trans.lv = UI/AdministrationUI/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/AdministrationUI/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/AdministrationUI/Dutch.lproj/Localizable.strings
@@ -260,11 +274,13 @@ trans.es_ES = SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Appointments/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Appointments/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Appointments/French.lproj/Localizable.strings
trans.he = SoObjects/Appointments/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Appointments/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Appointments/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Appointments/Icelandic.lproj/Localizable.strings
trans.it = SoObjects/Appointments/Italian.lproj/Localizable.strings
trans.lt = SoObjects/Appointments/Lithuanian.lproj/Localizable.strings
trans.lv = SoObjects/Appointments/Latvian.lproj/Localizable.strings
trans.mk_MK = SoObjects/Appointments/Macedonian.lproj/Localizable.strings
trans.nb_NO = SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
trans.nl = SoObjects/Appointments/Dutch.lproj/Localizable.strings
@@ -295,11 +311,13 @@ trans.es_ES = SoObjects/Contacts/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Contacts/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Contacts/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Contacts/French.lproj/Localizable.strings
trans.he = SoObjects/Contacts/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Contacts/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Contacts/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Contacts/Icelandic.lproj/Localizable.strings
trans.it = SoObjects/Contacts/Italian.lproj/Localizable.strings
trans.lt = SoObjects/Contacts/Lithuanian.lproj/Localizable.strings
trans.lv = SoObjects/Contacts/Latvian.lproj/Localizable.strings
trans.mk_MK = SoObjects/Contacts/Macedonian.lproj/Localizable.strings
trans.nb_NO = SoObjects/Contacts/NorwegianBokmal.lproj/Localizable.strings
trans.nl = SoObjects/Contacts/Dutch.lproj/Localizable.strings
@@ -330,11 +348,13 @@ trans.es_ES = SoObjects/Mailer/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Mailer/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Mailer/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Mailer/French.lproj/Localizable.strings
trans.he = SoObjects/Mailer/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Mailer/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Mailer/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Mailer/Icelandic.lproj/Localizable.strings
trans.it = SoObjects/Mailer/Italian.lproj/Localizable.strings
trans.lt = SoObjects/Mailer/Lithuanian.lproj/Localizable.strings
trans.lv = SoObjects/Mailer/Latvian.lproj/Localizable.strings
trans.mk_MK = SoObjects/Mailer/Macedonian.lproj/Localizable.strings
trans.nb_NO = SoObjects/Mailer/NorwegianBokmal.lproj/Localizable.strings
trans.nl = SoObjects/Mailer/Dutch.lproj/Localizable.strings
@@ -365,11 +385,13 @@ trans.es_ES = UI/MailPartViewers/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MailPartViewers/Basque.lproj/Localizable.strings
trans.fi = UI/MailPartViewers/Finnish.lproj/Localizable.strings
trans.fr = UI/MailPartViewers/French.lproj/Localizable.strings
trans.he = UI/MailPartViewers/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MailPartViewers/Croatian.lproj/Localizable.strings
trans.hu = UI/MailPartViewers/Hungarian.lproj/Localizable.strings
trans.is = UI/MailPartViewers/Icelandic.lproj/Localizable.strings
trans.it = UI/MailPartViewers/Italian.lproj/Localizable.strings
trans.lt = UI/MailPartViewers/Lithuanian.lproj/Localizable.strings
trans.lv = UI/MailPartViewers/Latvian.lproj/Localizable.strings
trans.mk_MK = UI/MailPartViewers/Macedonian.lproj/Localizable.strings
trans.nb_NO = UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
trans.nl = UI/MailPartViewers/Dutch.lproj/Localizable.strings
+95 -4
View File
@@ -83,7 +83,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSArray *emails, *addresses, *categories, *elements;
CardElement *n, *homeAdr, *workAdr;
NSMutableArray *other_addresses;
CardElement *n, *homeAdr, *workAdr, *otherAdr;
NSMutableString *s, *a;
NSString *url;
id o;
@@ -186,7 +187,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [homeAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", [a activeSyncRepresentationInContext: context]];
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", a];
if ((o = [homeAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<HomeCity xmlns=\"Contacts:\">%@</HomeCity>", [o activeSyncRepresentationInContext: context]];
@@ -217,7 +218,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [workAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", [a activeSyncRepresentationInContext: context]];
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", a];
if ((o = [workAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<BusinessCity xmlns=\"Contacts:\">%@</BusinessCity>", [o activeSyncRepresentationInContext: context]];
@@ -232,6 +233,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendFormat: @"<BusinessCountry xmlns=\"Contacts:\">%@</BusinessCountry>", [o activeSyncRepresentationInContext: context]];
}
// Other Address
other_addresses = [[self childrenWithTag: @"adr"] mutableCopy];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"work"]];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"home"]];
if ([other_addresses count])
{
otherAdr = [other_addresses objectAtIndex: 0];
a = [NSMutableString string];
if ((o = [otherAdr flattenedValueAtIndex: 2 forKey: @""]))
[a appendString: [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<OtherStreet xmlns=\"Contacts:\">%@</OtherStreet>", a];
if ((o = [otherAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<OtherCity xmlns=\"Contacts:\">%@</OtherCity>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 4 forKey: @""]))
[s appendFormat: @"<OtherState xmlns=\"Contacts:\">%@</OtherState>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 5 forKey: @""]))
[s appendFormat: @"<OtherPostalCode xmlns=\"Contacts:\">%@</OtherPostalCode>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 6 forKey: @""]))
[s appendFormat: @"<OtherCountry xmlns=\"Contacts:\">%@</OtherCountry>", [o activeSyncRepresentationInContext: context]];
}
// Other, less important fields
if ((o = [self birthday]))
{
@@ -267,7 +301,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inContext: (WOContext *) context
{
CardElement *element;
NSMutableArray *addressLines;
NSMutableArray *addressLines, *other_addresses;
id o;
// Contact's note
@@ -398,6 +432,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
atIndex: 6 forKey: @""];
}
// OtherCountry
//
other_addresses = [[self childrenWithTag: @"adr"] mutableCopy];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"work"]];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"home"]];
if ([other_addresses count])
element = [other_addresses objectAtIndex: 0];
else
{
element = [CardElement elementWithTag: @"adr"];
[self addChild: element];
}
if ((o = [theValues objectForKey: @"OtherStreet"]) || ![self _isGhosted: @"OtherStreet" inContext: context])
{
addressLines = [NSMutableArray arrayWithArray: [o componentsSeparatedByString: @"\n"]];
[element setSingleValue: @""
atIndex: 1 forKey: @""];
[element setSingleValue: [addressLines count] ? [addressLines objectAtIndex: 0] : @""
atIndex: 2 forKey: @""];
// Extended address line. If there are more then 2 address lines we add them to the extended address line.
if ([addressLines count] > 1)
{
[addressLines removeObjectAtIndex: 0];
[element setSingleValue: [addressLines componentsJoinedByString: @" "]
atIndex: 1 forKey: @""];
}
}
if ((o = [theValues objectForKey: @"OtherCity"]) || ![self _isGhosted: @"OtherCity" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherCity"]
atIndex: 3 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherState"]) || ![self _isGhosted: @"OtherState" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherState"]
atIndex: 4 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherPostalCode"]) || ![self _isGhosted: @"OtherPostalCode" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherPostalCode"]
atIndex: 5 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherCountry"]) || ![self _isGhosted: @"OtherCountry" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherCountry"]
atIndex: 6 forKey: @""];
}
// Company's name
if ((o = [theValues objectForKey: @"CompanyName"]))
[self setOrg: o units: nil];
+9
View File
@@ -148,6 +148,10 @@ static NSArray *easCommandParameters = nil;
const char* qs_bytes;
queryString = [[components objectAtIndex: 0] dataByDecodingBase64];
if (![queryString length])
return nil;
qs_bytes = (const char*)[queryString bytes];
return [NSString stringWithFormat:@"%.1f", (float)((uint8_t)qs_bytes[0]/10)];
@@ -196,6 +200,11 @@ static NSArray *easCommandParameters = nil;
// Command code, 1 byte, ie.: cmd=
cmd_code = qs_bytes[1];
// Check whether the command code is within the known range.
if (cmd_code < 0 || cmd_code > 22)
return nil;
[components addObject: [NSString stringWithFormat: @"cmd=%@", [easCommandCodes objectAtIndex: cmd_code]]];
// Device ID length and Device ID (variable)
+95 -12
View File
@@ -53,9 +53,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <SOGo/SOGoCacheGCSObject.h>
#import <SOGo/SOGoPermissions.h>
#import <NGCards/iCalCalendar.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#import <Appointments/SOGoAppointmentObject.h>
#import <Appointments/SOGoTaskObject.h>
#import <Appointments/SOGoAppointmentFolder.h>
#import <Contacts/SOGoContactGCSEntry.h>
@@ -227,7 +230,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
return nameInCache;
}
- (void) _removeAllAlarmsFromCalendar: (iCalCalendar *) theCalendar
{
NSArray *allComponents;
iCalEntityObject *currentComponent;
NSUInteger count, max;
if (debugOn)
[self logWithFormat: @"EAS - Remove all alarms"];
allComponents = [theCalendar allObjects];
max = [allComponents count];
for (count = 0; count < max; count++)
{
currentComponent = [allComponents objectAtIndex: count];
if ([currentComponent isKindOfClass: [iCalEvent class]] ||
[currentComponent isKindOfClass: [iCalToDo class]])
[currentComponent removeAllAlarms];
}
}
//
// <?xml version="1.0"?>
@@ -269,6 +291,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncAddCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
objectsToTouch: (NSMutableArray *) objectsToTouch
inBuffer: (NSMutableString *) theBuffer
{
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *uidCache, *allValues;
@@ -280,6 +303,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
int i;
additions = (id)[theDocumentElement getElementsByTagName: @"Add"];
if ([additions count])
{
for (i = 0; i < [additions count]; i++)
@@ -307,8 +331,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// the case, let's just update it. This can happen if for example, an iOS based device receives the
// invitation email and choses "Add to calendar" BEFORE actually syncing the calendar. That would
// create a duplicate on the server.
if ([allValues objectForKey: @"UID"])
serverId = [allValues objectForKey: @"UID"];
if ([allValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"])
serverId = [allValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"];
else
serverId = [theCollection globallyUniqueObjectId];
@@ -343,9 +367,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
case ActiveSyncMailFolder:
default:
{
// FIXME - what to do?
[self errorWithFormat: @"Fatal error occured - tried to call -processSyncAddCommand: ... on a mail folder. We abort."];
abort();
// Support SMS to Exchange eMail sync.
NSString *serverId;
sogoObject = [SOGoMailObject objectWithName: @"Mail" inContainer: theCollection];
serverId = [sogoObject storeMail: allValues inContext: context];
if (serverId)
{
// Everything is fine, lets generate our response
// serverId = clientId - There is no furhter processing after adding the SMS to the inbox.
[theBuffer appendString: @"<Add>"];
[theBuffer appendFormat: @"<ClientId>%@</ClientId>", clientId];
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Add>"];
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
syncCache = [folderMetadata objectForKey: @"SyncCache"];
[syncCache setObject: @"0" forKey: serverId];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
continue;
}
else
{
// FIXME - what to do?
[self errorWithFormat: @"Fatal error occured - tried to call -processSyncAddCommand: ... on a mail folder. We abort."];
abort();
}
}
}
@@ -367,9 +415,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
[o takeActiveSyncValues: allValues inContext: context];
[sogoObject setIsNew: is_new];
[sogoObject saveComponent: o];
if (theFolderType == ActiveSyncEventFolder)
[sogoObject saveComponent: o force: YES];
else
[sogoObject saveComponent: o];
}
if ([sogoObject isKindOfClass: [SOGoAppointmentObject class]] && [sogoObject resourceHasAutoAccepted])
[objectsToTouch addObject: sogoObject];
// Update syncCache
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
@@ -421,7 +477,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", easId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Add>"];
}
}
}
@@ -465,7 +520,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncChangeCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
objectsToTouch: (NSMutableArray *) objectsToTouch
inBuffer: (NSMutableString *) theBuffer
{
NSDictionary *allChanges;
NSString *serverId, *easId, *origServerId, *mergedFolder;
@@ -505,6 +561,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncChangeCommand: theDocumentElement
inCollection: [self collectionFromId: mergedFolder type: theFolderType]
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
continue;
@@ -588,7 +645,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ([roles containsObject: SOGoCalendarRole_ComponentModifier] || [[sogoObject ownerInContext: context] isEqualToString: [[context activeUser] login]])
{
[o takeActiveSyncValues: allChanges inContext: context];
[sogoObject saveComponent: o];
if (theFolderType == ActiveSyncEventFolder)
{
[sogoObject saveComponent: o force: YES];
if ([sogoObject resourceHasAutoAccepted])
[objectsToTouch addObject: sogoObject];
}
else
[sogoObject saveComponent: o];
if ([syncCache objectForKey: serverId])
[syncCache setObject: [NSString stringWithFormat: @"%f", [[sogoObject lastModified] timeIntervalSince1970]] forKey: serverId];
@@ -748,7 +813,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
roles = [theCollection aclsForUser:[[context activeUser] login]];
// We check ACLs on the collection and not on the SOGo object itself, as the add/delete rights are on the collection itself
if (![roles containsObject: SOGoRole_ObjectEraser] || ![[sogoObject ownerInContext: context] isEqualToString: [[context activeUser] login]])
if (![roles containsObject: SOGoRole_ObjectEraser] && ![[sogoObject ownerInContext: context] isEqualToString: [[context activeUser] login]])
{
// This will trigger an add-command to re-add the component to the client
[sogoObject touch];
@@ -1202,6 +1267,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
d = [NSCalendarDate distantFuture];
[dateCache setObject: d forKey: uid];
if (!([theCollection showCalendarAlarms]))
[self _removeAllAlarmsFromCalendar: [componentObject parent]];
}
if (updated)
@@ -1562,7 +1630,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: [mailObject activeSyncRepresentationInContext: context]];
[s appendString: @"</ApplicationData>"];
[s appendString: @"</Add>"];
[syncCache setObject: [aCacheObject sequence] forKey: [aCacheObject uid]];
[dateCache setObject: [NSCalendarDate date] forKey: [aCacheObject uid]];
@@ -1637,6 +1705,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
objectsToTouch: (NSMutableArray *) objectsToTouch
processed: (BOOL *) processed
{
id <DOMElement> aCommand, element;
@@ -1665,6 +1734,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncAddCommand: element
inCollection: theCollection
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
*processed = YES;
}
@@ -1674,6 +1744,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncChangeCommand: element
inCollection: theCollection
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
*processed = YES;
}
@@ -1711,7 +1782,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *mimeSupport, *mimeTruncation, *filterType, *lastServerKey, *syncKeyInCache, *folderKey;
NSMutableDictionary *folderMetadata, *folderOptions;
NSMutableArray *supportedElements, *supportedElementNames;
NSMutableArray *supportedElements, *supportedElementNames, *objectsToTouch;
NSMutableString *changeBuffer, *commandsBuffer;
id collection, value;
@@ -1941,6 +2012,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// We process the commands from the request
//
objectsToTouch = [NSMutableArray array];
if (!first_sync)
{
NSMutableString *s;
@@ -1953,6 +2026,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inCollection: collection
withType: folderType
inBuffer: s
objectsToTouch: objectsToTouch
processed: &processed];
// Windows phones don't like empty Responses tags - such as: <Responses></Responses>.
@@ -2271,6 +2345,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendString: changeBuffer];
[theBuffer appendString: @"</Collection>"];
// We touch objects (likely only SOGoAppointmentObjects for now) that might have been changed
// by the server and that we want the EAS client to re-pull. For example, that's the case for
// auto-accepted events by resources
for (i = 0; i < [objectsToTouch count]; i++)
{
sleep(1);
[[objectsToTouch objectAtIndex: i] touch];
}
}
//
+213 -95
View File
@@ -43,6 +43,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGObjWeb/WOCoreApplication.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalPerson.h>
#import <NGExtensions/NGBase64Coding.h>
@@ -59,8 +61,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeFileData.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGMimeType.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGConcreteMimeType.h>
#import <NGMail/NGMimeMessageParser.h>
#import <NGMail/NGMimeMessageGenerator.h>
@@ -947,6 +950,7 @@ void handle_eas_terminate(int signum)
command_count++;
}
[o destroy];
continue;
}
// Remove the folder from device if it is a contact folder and we have no SOGoRole_ObjectViewer.
@@ -1097,6 +1101,7 @@ void handle_eas_terminate(int signum)
![currentFolder synchronize])
{
[folders removeObjectAtIndex: count];
continue;
}
// Remove the folder from the device if it is a contact folder and we have no SOGoRole_ObjectViewer access right.
@@ -1146,38 +1151,45 @@ void handle_eas_terminate(int signum)
name = [NSString stringWithFormat: @"vtodo/%@", [[folders objectAtIndex:fi] nameInContainer]];
type = ([[[folders objectAtIndex:fi] nameInContainer] isEqualToString: personalFolderName] ? 7 : 15);
[commands appendFormat: @"<%@><ServerId>%@</ServerId><ParentId>%@</ParentId><DisplayName>%@</DisplayName><Type>%d</Type></%@>", operation,
[name stringByEscapingURL], @"0", [[[folders objectAtIndex:fi] displayName] activeSyncRepresentationInContext: context], type, operation];
command_count++;
key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], name];
o = [SOGoCacheGCSObject objectWithName: key inContainer: nil];
[o setObjectType: ActiveSyncFolderCacheObject];
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
[[o properties ] setObject: [[folders objectAtIndex:fi] displayName] forKey: @"displayName"];
if ([operation isEqualToString: @"Add"])
// We always sync the "Default Tasks folder" (7). For "User-created Tasks folder" (15), we check if we include it in
// the sync process by checking if "Show tasks" is enabled. If not, we skip the folder entirely.
if (type == 7 ||
(type == 15 && [[folders objectAtIndex: fi] showCalendarTasks]))
{
// clean cache content to avoid stale data
[[o properties] removeObjectForKey: @"SyncKey"];
[[o properties] removeObjectForKey: @"SyncCache"];
[[o properties] removeObjectForKey: @"DateCache"];
[[o properties] removeObjectForKey: @"UidCache"];
[[o properties] removeObjectForKey: @"MoreAvailable"];
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
[[o properties] removeObjectForKey: @"SupportedElements"];
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
[[o properties] removeObjectForKey: @"FirstIdInCache"];
[[o properties] removeObjectForKey: @"LastIdInCache"];
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
[[o properties] removeObjectForKey: @"MergedFolder"];
[[o properties] removeObjectForKey: @"CleanoutDate"];
}
[commands appendFormat: @"<%@><ServerId>%@</ServerId><ParentId>%@</ParentId><DisplayName>%@</DisplayName><Type>%d</Type></%@>", operation,
[name stringByEscapingURL], @"0", [[[folders objectAtIndex:fi] displayName] activeSyncRepresentationInContext: context], type, operation];
[o save];
command_count++;
key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], name];
o = [SOGoCacheGCSObject objectWithName: key inContainer: nil];
[o setObjectType: ActiveSyncFolderCacheObject];
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
[[o properties ] setObject: [[folders objectAtIndex:fi] displayName] forKey: @"displayName"];
if ([operation isEqualToString: @"Add"])
{
// clean cache content to avoid stale data
[[o properties] removeObjectForKey: @"SyncKey"];
[[o properties] removeObjectForKey: @"SyncCache"];
[[o properties] removeObjectForKey: @"DateCache"];
[[o properties] removeObjectForKey: @"UidCache"];
[[o properties] removeObjectForKey: @"MoreAvailable"];
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
[[o properties] removeObjectForKey: @"SupportedElements"];
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
[[o properties] removeObjectForKey: @"FirstIdInCache"];
[[o properties] removeObjectForKey: @"LastIdInCache"];
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
[[o properties] removeObjectForKey: @"MergedFolder"];
[[o properties] removeObjectForKey: @"CleanoutDate"];
}
[o save];
}
}
else if ([[folders objectAtIndex:fi] isKindOfClass: [SOGoContactGCSFolder class]])
{
@@ -1210,8 +1222,8 @@ void handle_eas_terminate(int signum)
[o save];
}
}
}
} // if (operation)
} // for (fi = 0; fi <= count ; fi++)
// set a new syncKey if there are folder changes
@@ -1815,7 +1827,7 @@ void handle_eas_terminate(int signum)
{
appointmentObject = [[SOGoAppointmentObject alloc] initWithName: [NSString stringWithFormat: @"%@.ics", [event uid]]
inContainer: collection];
[appointmentObject saveComponent: event];
[appointmentObject saveComponent: event force: YES];
}
if (uidCache && [calendarId length] > 64)
@@ -2651,6 +2663,7 @@ void handle_eas_terminate(int signum)
NSData *d;
unsigned int startdate, enddate, increments;
NGCalendarDateRange *r1, *r2;
char c;
startDate = [[[(id)[theDocumentElement getElementsByTagName: @"StartTime"] lastObject] textValue] calendarDate];
@@ -2697,17 +2710,13 @@ void handle_eas_terminate(int signum)
folder = [user personalCalendarFolderInContext: context];
freebusy = [folder fetchFreeBusyInfosFrom: startDate to: endDate];
NGCalendarDateRange *r1, *r2;
for (j = 1; j <= increments; j++)
for (j = 0; j < increments; j++)
{
c = '0';
r1 = [NGCalendarDateRange calendarDateRangeWithStartDate: [NSDate dateWithTimeIntervalSince1970: (startdate+j*30*60)]
endDate: [NSDate dateWithTimeIntervalSince1970: (startdate+j*30*60 + 30)]];
for (k = 0; k < [freebusy count]; k++)
{
@@ -2725,11 +2734,8 @@ void handle_eas_terminate(int signum)
[s appendFormat: @"%c", c];
}
[s appendString: @"</MergedFreeBusy>"];
[s appendString: @"</Availability>"];
[s appendString: @"</Recipient>"];
[s appendString: @"</Response>"];
}
@@ -2760,7 +2766,7 @@ void handle_eas_terminate(int signum)
inResponse: (WOResponse *) theResponse
{
SOGoContactSourceFolder *currentFolder;
NSArray *allKeys, *allContacts, *mails;
NSArray *allKeys, *allContacts, *mails, *a;
NSDictionary *systemSources, *contact;
SOGoContactFolders *contactFolders;
NSString *current_mail, *query;
@@ -2770,7 +2776,10 @@ void handle_eas_terminate(int signum)
NSData *d;
id o;
int i, j, total;
int i, j, t, v, total, minResult, maxResult, maxSize, maxPictures;
BOOL withPhoto;
withPhoto = NO;
query = [[(id)[theDocumentElement getElementsByTagName: @"Query"] lastObject] textValue];
@@ -2779,6 +2788,33 @@ void handle_eas_terminate(int signum)
systemSources = [contactFolders systemSources];
allKeys = [systemSources allKeys];
// We check for the maximum number of results to return.
a = [[[(id)[theDocumentElement getElementsByTagName: @"Range"] lastObject] textValue] componentsSeparatedByString: @"-"];
minResult = [[a objectAtIndex: 0] intValue];
maxResult = [[a objectAtIndex: 1] intValue];
if (maxResult == 0)
maxResult = 99;
if ((o = [(id)[[(id)[theDocumentElement getElementsByTagName: @"Options"] lastObject] getElementsByTagName: @"Picture"] lastObject]))
{
withPhoto = YES;
// We check for a MaxSize, default to 102400.
maxSize = [[[(id)[o getElementsByTagName: @"MaxSize"] lastObject] textValue] intValue];
// We check if we must overwrite the maxSize with a system preference. This can be useful
// if we don't want to have pictures in the response.
if ((v = [[SOGoSystemDefaults sharedSystemDefaults] maximumPictureSize]))
maxSize = v;
// We check for a MaxPictures, default to 99.
maxPictures = [[[(id)[o getElementsByTagName: @"MaxPictures"] lastObject] textValue] intValue];
if (maxPictures == 0)
maxPictures = 99;
}
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
@@ -2800,7 +2836,7 @@ void handle_eas_terminate(int signum)
ordering: NSOrderedAscending
inDomain: [[context activeUser] domain]];
for (j = 0; j < [allContacts count]; j++)
for (j = minResult; (j < [allContacts count] && j < maxResult) ; j++)
{
contact = [allContacts objectAtIndex: j];
@@ -2818,42 +2854,60 @@ void handle_eas_terminate(int signum)
else
mails = [NSArray arrayWithObjects: o ? o : @"", nil];
for (total = 0; total < [mails count]; total++)
for (t = 0; t < [mails count]; t++)
{
current_mail = [mails objectAtIndex: total];
current_mail = [mails objectAtIndex: t];
[s appendString: @"<Result xmlns=\"Search:\">"];
[s appendString: @"<Properties>"];
if ((o = [contact objectForKey: @"displayname"]))
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", o];
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"title"]))
[s appendFormat: @"<Title xmlns=\"Gal:\">%@</Title>", o];
[s appendFormat: @"<Title xmlns=\"Gal:\">%@</Title>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"givenname"]))
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", o];
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"sn"]))
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", o];
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", [o activeSyncRepresentationInContext: context]];
if ([current_mail length] > 0)
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", current_mail];
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", [current_mail activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"telephonenumber"]))
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", o];
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"homephone"]))
[s appendFormat: @"<HomePhone xmlns=\"Gal:\">%@</HomePhone>", o];
[s appendFormat: @"<HomePhone xmlns=\"Gal:\">%@</HomePhone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"mobile"]))
[s appendFormat: @"<MobilePhone xmlns=\"Gal:\">%@</MobilePhone>", o];
[s appendFormat: @"<MobilePhone xmlns=\"Gal:\">%@</MobilePhone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"o"]))
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", o];
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", [o activeSyncRepresentationInContext: context]];
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.1 && withPhoto)
{
o = [contact objectForKey: @"photo"];
if (o && [o length] <= maxSize && total < maxPictures)
{
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>1</Status><Data>"];
[s appendString: [o activeSyncRepresentationInContext: context]];
[s appendString: @"</Data></Picture>"];
}
else if (!o)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>173</Status></Picture>"];
else if ([o length] > maxSize)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>174</Status></Picture>"];
else if (total >= maxPictures)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>175</Status></Picture>"];
}
[s appendString: @"</Properties>"];
[s appendString: @"</Result>"];
total++;
}
}
}
@@ -3167,6 +3221,28 @@ void handle_eas_terminate(int signum)
return nil;
}
//
// See https://msdn.microsoft.com/en-us/library/ee218647(v=exchg.80).aspx
// for valid status codes.
//
- (NSData *) _sendMailErrorResponseWithStatus: (int) status
{
NSMutableString *s;
NSData *d;
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<SendMail xmlns=\"ComposeMail:\">"];
[s appendFormat: @"<Status>%d</Status>", status];
[s appendString: @"</SendMail>"];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
return d;
}
//
//
//
@@ -3180,6 +3256,7 @@ void handle_eas_terminate(int signum)
NSData *new_from_header;
NSDictionary *identity;
NSString *fullName, *email;
NGMimeType *contentType;
NSArray *from;
const char *bytes;
@@ -3195,6 +3272,40 @@ void handle_eas_terminate(int signum)
message = [parser parsePartFromData: data];
RELEASE(parser);
// If an EAS client is trying to send an invitation email (request or response), we make sure to
// remove all attendees that have NO email addresses. Outlook 2016 (and likely other EAS clients)
// do that when sending IMIP only to "newly added or deleted attendees" - existing attendees have
// their email addresses stripped, while keeping the display name value.
contentType = [message contentType];
if ([contentType isKindOfClass: [NGConcreteTextMimeType class]] &&
[[[message contentType] subType] caseInsensitiveCompare: @"calendar"] == NSOrderedSame &&
([[(NGConcreteTextMimeType *)[message contentType] method] caseInsensitiveCompare: @"request"] == NSOrderedSame ||
[[(NGConcreteTextMimeType *)[message contentType] method] caseInsensitiveCompare: @"reply"] == NSOrderedSame))
{
NGMimeMessageGenerator *generator;
iCalCalendar *calendar;
iCalPerson *attendee;
NSArray *attendees;
iCalEvent *event;
calendar = [iCalCalendar parseSingleFromSource: [message body]];
event = [[calendar events] lastObject];
attendees = [event attendees];
for (i = [attendees count]-1; i >= 0; i--)
{
attendee = [attendees objectAtIndex: i];
if (![attendee rfc822Email] || [[attendee rfc822Email] caseInsensitiveCompare: @"nomail"] == NSOrderedSame)
[event removeFromAttendees: attendee];
}
// We regenerate the data to use
[message setBody: [[calendar versitString] dataUsingEncoding: NSUTF8StringEncoding]];
generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
data = [NSMutableData dataWithData: [generator generateMimeFromPart: message]];
}
from = [message headersForKey: @"from"];
if (![from count] || ![self _isEMailValid: [[from objectAtIndex: 0] pureEMailAddress]] ||
@@ -3296,20 +3407,7 @@ void handle_eas_terminate(int signum)
{
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.0)
{
NSMutableString *s;
NSData *d;
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<SendMail xmlns=\"ComposeMail:\">"];
[s appendString: @"<Status>120</Status>"];
[s appendString: @"</SendMail>"];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
[theResponse setContent: d];
[theResponse setContent: [self _sendMailErrorResponseWithStatus: 120]];
}
else
{
@@ -3498,10 +3596,14 @@ void handle_eas_terminate(int signum)
{
NSString *folderId, *itemId, *realCollectionId;
SOGoMicrosoftActiveSyncFolderType folderType;
SOGoMailAccounts *accountsFolder;
SOGoMailFolder *currentFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
SOGoUserDefaults *ud;
BOOL htmlComposition, isHTML;
id value;
id value, currentCollection;
isHTML = NO;
ud = [[context activeUser] userDefaults];
@@ -3527,23 +3629,31 @@ void handle_eas_terminate(int signum)
value = [theDocumentElement getElementsByTagName: @"ReplaceMime"];
// We fetch the mail object from the server
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", realCollectionId]
inContext: context
acquire: NO];
mailObject = [currentCollection lookupName: itemId inContext: context acquire: NO];
// ReplaceMime IS specified so we must NOT use the server copy
// but rather take the data as-is from the client.
if ([value count])
{
[self processSendMail: theDocumentElement
inResponse: theResponse];
[self processSendMail: theDocumentElement inResponse: theResponse];
if (!isSmartForward)
[mailObject addFlags: @"Answered"];
else
[mailObject addFlags: @"$Forwarded"];
return;
}
if (folderType == ActiveSyncMailFolder)
{
SOGoMailAccounts *accountsFolder;
SOGoMailFolder *currentFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
id currentCollection;
NGMimeMessage *messageFromSmartForward, *messageToSend;
NGMimeMessageParser *parser;
NSData *data;
@@ -3562,16 +3672,6 @@ void handle_eas_terminate(int signum)
int a;
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", realCollectionId]
inContext: context
acquire: NO];
mailObject = [currentCollection lookupName: itemId inContext: context acquire: NO];
parser = [[NGMimeMessageParser alloc] init];
data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding];
messageFromSmartForward = [parser parsePartFromData: data];
@@ -3937,6 +4037,14 @@ void handle_eas_terminate(int signum)
// Get the device ID, device type and "stash" them
deviceId = [[theRequest uri] deviceId];
if ([deviceId isEqualToString: @"Unknown"])
{
[(WOResponse *)theResponse setStatus: 500];
[self logWithFormat: @"EAS - No device id provided, ignoring request."];
return nil;
}
[context setObject: deviceId forKey: @"DeviceId"];
[context setObject: [[theRequest uri] deviceType] forKey: @"DeviceType"];
[context setObject: [[theRequest uri] attachmentName] forKey: @"AttachmentName"];
@@ -3993,23 +4101,32 @@ void handle_eas_terminate(int signum)
}
xml = [NSString stringWithFormat: @"<?xml version=\"1.0\"?><!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\"><%@ xmlns=\"ComposeMail:\"><SaveInSentItems/><MIME>%@</MIME></%@>", cmdName, [s stringByEncodingBase64], cmdName];
d = [xml dataUsingEncoding: NSASCIIStringEncoding];
}
else
{
d = [[theRequest content] wbxml2xml];
// Handle empty Ping request, no need to try decoding the WBXML blob here
if ([[theRequest content] length])
d = [[theRequest content] wbxml2xml];
else
d = nil;
}
documentElement = nil;
if (!d)
{
// If we got no data in the SendMail request, that means SOPE rejected it because of the WOMaxUploadSize.
// We generate here the proper failed response for SendMail
if ([cmdName caseInsensitiveCompare: @"SendMail"] == NSOrderedSame)
{
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
[theResponse setContent: [self _sendMailErrorResponseWithStatus: 122]];
goto return_response;
}
// We check if it's a Ping command with no body.
// See http://msdn.microsoft.com/en-us/library/ee200913(v=exchg.80).aspx for details
if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame)
else if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame)
{
RELEASE(context);
RELEASE(pool);
@@ -4047,6 +4164,7 @@ void handle_eas_terminate(int signum)
[self performSelector: aSelector withObject: documentElement withObject: theResponse];
return_response:
[theResponse setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"];
[theResponse setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
[theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
+2
View File
@@ -42,6 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
- (NSString *) storeMail: (NSDictionary *) theValues
inContext: (WOContext *) _context;
@end
+163 -37
View File
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
#import <Foundation/NSTimeZone.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
@@ -44,9 +45,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSString+Encoding.h>
#import <NGExtensions/NGHashMap.h>
#import <NGImap4/NGImap4Envelope.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
#import <NGImap4/NSString+Imap4.h>
#import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4Client.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WORequest.h>
@@ -60,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGMail/NGMimeMessageGenerator.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserFolder.h>
#include "iCalTimeZone+ActiveSync.h"
#include "NSData+ActiveSync.h"
@@ -71,6 +76,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <Mailer/SOGoMailBodyPart.h>
#include <Mailer/NSString+Mail.h>
#import <Mailer/SOGoMailLabel.h>
#import <Mailer/SOGoMailFolder.h>
#import <Mailer/SOGoMailObject.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#include <SOGo/SOGoUser.h>
#include <SOGo/NSString+Utilities.h>
@@ -163,7 +174,7 @@ struct GlobalObjectId {
const char *bytes;
uid = [event uid];
uidAsASCII = [uid decodeFromHexidecimal];
uidAsASCII = [uid dataUsingEncoding: NSASCIIStringEncoding];
newGlobalId = (struct GlobalObjectId*)calloc(sizeof(uint8_t), sizeof(struct GlobalObjectId) + 0x0c + [uidAsASCII length]);
prefix = @"040000008200e00074c5b7101a82e008";
@@ -726,12 +737,53 @@ struct GlobalObjectId {
//
//
//
- (iCalCalendar *) calendarFromIMIPMessage
- (iCalCalendar *) _calendarFromParts: (NSArray *) parts
parent: (id) parent
{
NSDictionary *part;
id bodyPart;
int i;
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
bodyPart = [parent lookupImap4BodyPartKey: [NSString stringWithFormat: @"%d", i+1]
inContext: self->context];
if ([[part objectForKey: @"type"] isEqualToString: @"text"] &&
[[part objectForKey: @"subtype"] isEqualToString: @"calendar"])
{
if (bodyPart)
{
iCalCalendar *calendar;
NSData *calendarData;
calendarData = [bodyPart fetchBLOBWithPeek: YES];
calendar = nil;
NS_DURING
calendar = [iCalCalendar parseSingleFromSource: calendarData];
NS_HANDLER
calendar = nil;
NS_ENDHANDLER
return calendar;
}
}
else if ([[part objectForKey: @"type"] isEqualToString: @"multipart"])
return [self _calendarFromParts: [part objectForKey: @"parts"] parent: bodyPart];
}
return nil;
}
//
//
//
- (iCalCalendar *) calendarFromIMIPMessage
{
NSString *type, *subtype;
NSArray *parts;
int i;
type = [[[self bodyStructure] valueForKey: @"type"] lowercaseString];
subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString];
@@ -764,38 +816,7 @@ struct GlobalObjectId {
parts = [[self bodyStructure] objectForKey: @"parts"];
if ([parts count] > 1)
{
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
if ([[part objectForKey: @"type"] isEqualToString: @"text"] &&
[[part objectForKey: @"subtype"] isEqualToString: @"calendar"])
{
id bodyPart;
bodyPart = [self lookupImap4BodyPartKey: [NSString stringWithFormat: @"%d", i+1]
inContext: self->context];
if (bodyPart)
{
iCalCalendar *calendar;
NSData *calendarData;
calendarData = [bodyPart fetchBLOBWithPeek: YES];
calendar = nil;
NS_DURING
calendar = [iCalCalendar parseSingleFromSource: calendarData];
NS_HANDLER
calendar = nil;
NS_ENDHANDLER
return calendar;
}
}
}
}
return [self _calendarFromParts: parts parent: self];
return nil;
}
@@ -934,7 +955,7 @@ struct GlobalObjectId {
else if ([method isEqualToString: @"COUNTER"])
className = @"IPM.Schedule.Meeting.Resp.Tent";
else if ([method isEqualToString: @"CANCEL"])
className = @"IPM.Schedule.Meeting.Cancelled";
className = @"IPM.Schedule.Meeting.Canceled";
else
className = @"IPM.Appointment";
@@ -962,7 +983,12 @@ struct GlobalObjectId {
// Location
if ([[event location] length])
[s appendFormat: @"<Location xmlns=\"Email:\">%@</Location>", [[event location] activeSyncRepresentationInContext: context]];
{
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0)
[s appendFormat: @"<Location xmlns=\"AirSyncBase:\"><DisplayName>%@</DisplayName></Location>", [[event location] activeSyncRepresentationInContext: context]];
else
[s appendFormat: @"<Location xmlns=\"Email:\">%@</Location>", [[event location] activeSyncRepresentationInContext: context]];
}
[s appendFormat: @"<Organizer xmlns=\"Email:\">%@</Organizer>", [[[event organizer] mailAddress] activeSyncRepresentationInContext: context]];
@@ -1422,4 +1448,104 @@ struct GlobalObjectId {
}
}
- (NSString *) storeMail: (NSDictionary *) theValues
inContext: (WOContext *) _context
{
NSString *dateReceived, *folder, *s;
NGMimeMessageGenerator *generator;
NGMimeMessage *bounceMessage;
NSDictionary *identity;
NGMutableHashMap *map;
NGImap4Client *client;
NSData *message_data;
id o, result;
int bodyType;
identity = [[context activeUser] primaryIdentity];
message_data = nil;
bodyType = 1;
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Type"]))
bodyType = [o intValue];
if (bodyType == 4)
{
s = [[theValues objectForKey: @"Body"] objectForKey: @"Data"];
message_data = [s dataUsingEncoding: NSUTF8StringEncoding];
}
if (bodyType == 1 || bodyType == 2)
{
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
[map setObject: [NSString stringWithFormat: @"%@ <%@>", [identity objectForKey: @"fullName"], [identity objectForKey: @"email"]] forKey: @"from"];
if ((o = [theValues objectForKey: @"To"]))
[map setObject: o forKey: @"to"];
if ((o = [theValues objectForKey: @"Subject"]))
[map setObject: o forKey: @"subject"];
o = [[theValues objectForKey: @"DateReceived"] calendarDate];
if (!o)
o = [NSCalendarDate date];
#if GNUSTEP_BASE_MINOR_VERSION < 21
dateReceived = [o descriptionWithCalendarFormat: @"%a, %d %b %Y %H:%M:%S %z"
timeZone: [NSTimeZone timeZoneWithName: @"GMT"]
locale: nil];
#else
dateReceived = [o descriptionWithCalendarFormat: @"%a, %d %b %Y %H:%M:%S %z"
timeZone: [NSTimeZone timeZoneWithName: @"GMT"]
locale: [NSDictionary dictionaryWithObjectsAndKeys:
[NSArray arrayWithObjects: @"Jan", @"Feb", @"Mar", @"Apr",
@"May", @"Jun", @"Jul", @"Aug",
@"Sep", @"Oct", @"Nov", @"Dec", nil],
@"NSShortMonthNameArray",
[NSArray arrayWithObjects: @"Sun", @"Mon", @"Tue", @"Wed", @"Thu",
@"Fri", @"Sat", nil],
@"NSShortWeekDayNameArray",
nil]];
#endif
[map setObject: dateReceived forKey: @"date"];
[map setObject: [NSString generateMessageID] forKey: @"message-id"];
[map setObject: (bodyType == 1 ? @"text/plain; charset=utf-8" : @"text/html; charset=utf-8")
forKey: @"content-type"];
[map setObject: @"quoted-printable" forKey: @"content-transfer-encoding"];
bounceMessage = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];
[bounceMessage setBody: [[NSString stringWithFormat: @"%@", [[theValues objectForKey: @"Body"] objectForKey: @"Data"] ] dataUsingEncoding: NSUTF8StringEncoding]];
generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
message_data = [generator generateMimeFromPart: bounceMessage];
}
if (message_data)
{
client = [[self imap4Connection] client];
if (![imap4 doesMailboxExistAtURL: [container imap4URL]])
{
[[self imap4Connection] createMailbox: [[self imap4Connection] imap4FolderNameForURL: [container imap4URL]]
atURL: [[self mailAccountFolder] imap4URL]];
[imap4 flushFolderHierarchyCache];
}
folder = [imap4 imap4FolderNameForURL: [container imap4URL]];
result = [client append: message_data
toFolder: folder
withFlags: [NSArray arrayWithObjects: @"draft", nil]];
if ([[result objectForKey: @"result"] boolValue])
return [NSString stringWithFormat: @"%d", [self IMAP4IDFromAppendResult: result]];
}
return nil;
}
@end
+48 -28
View File
@@ -36,6 +36,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalAlarm.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalTrigger.h>
#import <NGCards/NSCalendarDate+NGCards.h>
#include "NSDate+ActiveSync.h"
@implementation iCalAlarm (ActiveSync)
@@ -53,9 +56,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nextAlarmDate = [self nextAlarmDate];
delta = (int)(([[(iCalEvent *)parent startDate] timeIntervalSince1970] - [nextAlarmDate timeIntervalSince1970])/60);
// don't send negative reminder - not supported
if (delta > 0)
[s appendFormat: @"<Reminder xmlns=\"Calendar:\">%d</Reminder>", (int)delta];
if ([parent isKindOfClass: [iCalEvent class]])
{
// don't send negative reminder - not supported
if (delta > 0)
[s appendFormat: @"<Reminder xmlns=\"Calendar:\">%d</Reminder>", (int)delta];
}
else
{
[s appendFormat: @"<ReminderTime xmlns=\"Task:\">%@</ReminderTime>", [nextAlarmDate activeSyncRepresentationInContext: context]];
}
}
return s;
@@ -67,37 +77,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
iCalTrigger *trigger;
id o;
o = [theValues objectForKey: @"Reminder"];
// Outlook: if reminder is set to 0 minutes before start save it as 1 minute since -> 0 minutes in not accepted by SOGo
if ([o isEqualToString: @"0"])
o = @"1";
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DURATION"];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
// SOGo web ui only supports 1w but not 2w (custom reminder only supports min/hours/days)
// 1week = -P1W
// 2weeks > -PxD
// xdays > -PxD
// xhours -> -PTxH
// xmin -> -PTxM
if ([o intValue] == 10080)
[trigger setSingleValue: [NSString stringWithFormat: @"-P1W" ] forKey: @""];
else
if ((o = [theValues objectForKey: @"Reminder"]))
{
if (([o intValue] % 1440) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-P%dD", ([o intValue] / 1440)] forKey: @""];
// Outlook: if reminder is set to 0 minutes before starttime, save it as 1 minute since -> 0 minutes in not accepted by SOGo
if ([o isEqualToString: @"0"])
o = @"1";
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DURATION"];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
// SOGo web ui only supports 1w but not 2w (custom reminder only supports min/hours/days)
// 1week = -P1W
// 2weeks > -PxD
// xdays > -PxD
// xhours -> -PTxH
// xmin -> -PTxM
if ([o intValue] == 10080)
[trigger setSingleValue: [NSString stringWithFormat: @"-P1W" ] forKey: @""];
else
{
if (([o intValue] % 60) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%dH", ([o intValue] / 60)] forKey: @""];
if (([o intValue] % 1440) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-P%dD", ([o intValue] / 1440)] forKey: @""];
else
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%@M", o] forKey: @""];
{
if (([o intValue] % 60) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%dH", ([o intValue] / 60)] forKey: @""];
else
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%@M", o] forKey: @""];
}
}
}
else if ((o = [theValues objectForKey: @"ReminderTime"]))
{
o = [o calendarDate];
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DATE-TIME"];
[trigger setSingleValue: [NSString stringWithFormat: @"%@Z", [o iCalFormattedDateTimeString]] forKey: @""];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
}
}
@end
+26 -12
View File
@@ -231,9 +231,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
else
{
// If it's a normal event (ie, with no organizer/attendee) or we are the organizer to an event
// invitation, we set the busy status to 2 (Busy)
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", 2];
// If it's a normal event (i.e. with no organizer/attendee) or we are the organizer of an event
// invitation, we set the busy status depending on TRANSP.
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", (([self isOpaque]) ? 2 : 0)];
}
[s appendFormat: @"<MeetingStatus xmlns=\"Calendar:\">%d</MeetingStatus>", meetingStatus];
@@ -244,7 +244,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Location
if ([[self location] length])
[s appendFormat: @"<Location xmlns=\"Calendar:\">%@</Location>", [[self location] activeSyncRepresentationInContext: context]];
{
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0)
[s appendFormat: @"<Location xmlns=\"AirSyncBase:\"><DisplayName>%@</DisplayName></Location>", [[self location] activeSyncRepresentationInContext: context]];
else
[s appendFormat: @"<Location xmlns=\"Calendar:\">%@</Location>", [[self location] activeSyncRepresentationInContext: context]];
}
// Importance - NOT SUPPORTED - DO NOT ENABLE
//o = [self priority];
@@ -451,7 +456,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
occurences = [NSMutableArray arrayWithArray: [[self parent] events]];
if ((o = [theValues objectForKey: @"UID"]))
if ((o = [theValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"]))
[self setUid: o];
// FIXME: merge with iCalToDo
@@ -474,7 +479,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
if ((o = [theValues objectForKey: @"BusyStatus"]))
{
[o intValue];
if ([o boolValue])
[self setTransparency: @"OPAQUE"];
else
[self setTransparency: @"TRANSPARENT"];
}
//
@@ -527,8 +535,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setComment: o];
}
if ((o = [theValues objectForKey: @"Location"]))
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] < 16.0 && (o = [theValues objectForKey: @"Location"]))
[self setLocation: o];
else if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0 && (o = [theValues objectForKey: @"Location"]) && [o isKindOfClass: [NSDictionary class]])
[self setLocation: [o objectForKey: @"DisplayName"]];
deltasecs = 0;
start = nil;
@@ -579,7 +589,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// Ignore the alarm for now
}
else if ((o = [theValues objectForKey: @"Reminder"]))
else if ((o = [theValues objectForKey: @"Reminder"]) && [o length])
{
// NOTE: Outlook sends a 15 min reminder (18 hour for allday) if no reminder is specified
// although no default reminder is defined (File -> Options -> Clendar -> Calendar Options - > Default Reminders)
@@ -602,7 +612,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
// Recurrence
if ((o = [theValues objectForKey: @"Recurrence"]))
if ((o = [theValues objectForKey: @"Recurrence"]) && [o isKindOfClass: [NSDictionary class]])
{
iCalRecurrenceRule *rule;
@@ -830,7 +840,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
}
// Attendees - we don't touch the values if we're an attendee. This is gonna
// be done automatically by the ActiveSync client when invoking MeetingResponse.
if (![self userIsAttendee: [context activeUser]])
@@ -855,7 +864,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
person = [iCalPerson elementWithTag: @"attendee"];
[person setCn: [attendee objectForKey: @"Attendee_Name"]];
[person setEmail: [attendee objectForKey: @"Attendee_Email"]];
status = [[attendee objectForKey: @"Attendee_Status"] intValue];
switch (status)
@@ -872,7 +881,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
case 0:
case 5:
default:
[person setPartStat: @"NEEDS-ACTION"];
{
[person setPartStat: @"NEEDS-ACTION"];
[person setRsvp: @"TRUE"];
}
break;
}
@@ -884,6 +896,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setAttendees: attendees];
}
}
[self setLastModified: [NSCalendarDate calendarDate]];
}
- (void) changeParticipationStatus: (NSDictionary *) theValues
@@ -134,6 +134,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"%@:\">%d</Recurrence_DayOfWeek>", t, (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"%@:\">%d</Recurrence_WeekOfMonth>", t, firstOccurrence];
[s appendFormat: @"<Recurrence_Interval xmlns=\"%@:\">%d</Recurrence_Interval>", t, [self repeatInterval]];
}
else if ([[self byMonthDay] count])
{
@@ -149,6 +150,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dm = [self byDayMask];
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"%@:\">%d</Recurrence_DayOfWeek>", t, (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"%@:\">%d</Recurrence_WeekOfMonth>", t, 5];
[s appendFormat: @"<Recurrence_Interval xmlns=\"%@:\">%d</Recurrence_Interval>", t, [self repeatInterval]];
}
else
{
+25 -3
View File
@@ -43,9 +43,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalTimeZone.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
#include "iCalRecurrenceRule+ActiveSync.h"
#include "iCalAlarm+ActiveSync.h"
@implementation iCalToDo (ActiveSync)
@@ -95,8 +98,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
v = 1;
[s appendFormat: @"<Importance xmlns=\"Tasks:\">%d</Importance>", v];
// Reminder - FIXME
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
// Reminder
if ([self hasAlarms])
{
iCalAlarm *alarm;
alarm = [self firstDisplayOrAudioAlarm];
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 1];
[s appendString: [alarm activeSyncRepresentationInContext: context]];
}
else
{
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
}
// Sensitivity
if ([[self accessClass] isEqualToString: @"PRIVATE"])
@@ -145,7 +159,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @"</Body>"];
}
}
return s;
}
@@ -249,6 +263,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [theValues objectForKey: @"ReminderTime"]))
{
iCalAlarm *alarm;
alarm = [[iCalAlarm alloc] init];
[alarm takeActiveSyncValues: theValues inContext: context];
[self removeAllAlarms];
[self addToAlarms: alarm];
RELEASE(alarm);
}
+17459 -11064
View File
File diff suppressed because it is too large. Load diff
+3 -2
View File
@@ -2,7 +2,8 @@ all: $(patsubst %.asciidoc,%.pdf,$(wildcard *.asciidoc))
%.pdf : %.asciidoc
asciidoc -a docinfo1 -b docbook -d book -o $<.docbook $<
fop -c fonts/fop-config.xml -xsl docbook/xsl/sogo-fo.xsl -xml $<.docbook -pdf $@
xsltproc -o $<.fo docbook/xsl/sogo-fo.xsl $<.docbook
fop -c fonts/fop-config.xml $<.fo -pdf $@
clean:
rm *.asciidoc.docbook *.pdf
rm -f *.asciidoc.fo *.asciidoc.docbook *.pdf
+12 -6
View File
@@ -118,6 +118,11 @@ http://trochette.github.io/Angular-Design-Patterns-Best-Practices/
* Move business logic into models and share them.
* Keep it simple, separate server interaction and error handling from the model. That way model only handle data processing and code is easier to maintain.
Controllers
^^^^^^^^^^^
* Functions not exposed in the controller must be prefixed with an underscore.
SASS/CSS
~~~~~~~~
@@ -133,11 +138,6 @@ SASS/CSS
A `@mixin` is like a stamp: it creates a duplicated version of the property block (optionally) with arguments provided. An `@extend` appends the element you are extending to the property block. It is your "yes, and ___" statement.
* For documentation, we follow http://sassdoc.com/[SassDoc] annotations.
* We need the SASS files of Angular Material to build our CSS. The git repository of Angular Material is included as a submodule of SOGo:
git submodule init
git submodule update
* FlexBox compatibility http://caniuse.com/#feat=flexbox
Fonts
@@ -155,10 +155,16 @@ Building frontend
npm install -g grunt-cli
npm install -g bower
* Generate JavaScript files
* We need the SASS files of Angular Material to build our CSS. The git repository of Angular Material is included as a submodule of SOGo:
git submodule init
git submodule update
* Generate the JavaScript and CSS files
cd UI/WebServerResources
npm install
bower install
grunt build
Version Control
+70 -46
View File
@@ -47,7 +47,7 @@ and the data of Mozilla Thunderbird and Lightning
the SOGo Connector and the SOGo Integrator
* Native compatibility for Microsoft Outlook 2003, 2007, 2010, and 2013
* Two-way synchronization support with any Microsoft ActiveSync-capable
device, or Outlook 2013
device, or Outlook 2013/2016
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found at http://sogo.nu/
@@ -238,6 +238,14 @@ sources, install the following package:
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
----
SOGo relies on the GNUstep packages provided by Inverse and must not use the
packages from EPEL. Adjust the repository definition to exclude those packages:
----
sed -i '/enabled=1/a \
exclude=gnustep*' /etc/yum.repos.d/epel.repo
----
For more information on EPEL, visit http://fedoraproject.org/wiki/EPEL/.
Software Installation
@@ -391,9 +399,14 @@ internet connection could be killed prematurely.
|Parameter used to set the maximum allowed size for content being
sent to SOGo using a PUT or a POST call. This can also limit the file
attachment size being uploaded to SOGo when composing a mail. The
value is in kilobyte. By default, the value is 0, or disabled so no
value is in kilobytes. By default, the value is 0, or disabled so no
limit will be set.
|S |SOGoMaximumMessageSizeLimit
|Parameter used to set the maximum allowed email message size when
composing a mail. The value is in kilobytes. By default, the value is 0,
or disabled so no limit will be set.
|S |SxVMemLimit
|Parameter used to set the maximum amount of memory (in
megabytes) that a child can use. Reaching that value will force children
@@ -501,7 +514,7 @@ SOGoSAML2LogoutEnabled must be set to YES. If unset, the user will be
redirected to a blank page.
|D |SOGoTimeZone
|Parameter used to set a default time zone for users. The default
|Mandatory parameter used to set a default time zone for users. The default
timezone is set to UTC. The Olson database is a standard database that
takes all the time zones around the world into account and represents
them along with their history. On GNU/Linux systems, time zone
@@ -906,9 +919,9 @@ would be:
The following table describes the possible parameters related to a LDAP
source:
[cols="^3,>47,50a"]
[cols="3,47a,50"]
|=======================================================================
.36+|D <|SOGoUserSources
.36+^|D |SOGoUserSources
|Parameter used to set the LDAP and/or SQL sources used for
authentication and global address books. Multiple sources can be
specified as an array of dictionaries. A dictionary that defines an LDAP
@@ -1232,6 +1245,7 @@ mapping = {
2+h|Other
|Birthday |birthyear-birthmonth-birthday
|Note |description
|Photo |photo
|===
Authenticating using C.A.S.
@@ -1428,11 +1442,11 @@ settings:
----
SOGoProfileURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_user_profile";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_user_profile";
OCSFolderInfoURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_folder_info";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_folder_info";
OCSSessionsFolderURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_sessions_folder";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_sessions_folder";
----
The following table describes the parameters that were set:
@@ -1444,27 +1458,27 @@ The following table describes the parameters that were set:
profiles.
For MySQL, set the database URL to something like:
`mysql://sogo:sogo@localhost:3306/sogo/sogo_user_profile`.
`mysql://sogo:sogo@127.0.0.1:3306/sogo/sogo_user_profile`.
|S |OCSFolderInfoURL
|Parameter used to set the database URL so that SOGo can retrieve the
location of user folders (address books and calendars).
For Oracle, set the database URL to something like:
`oracle://sogo:sogo@localhost:1526/sogo/sogo_folder_info`.
`oracle://sogo:sogo@127.0.0.1:1526/sogo/sogo_folder_info`.
|S |OCSSessionsFolderURL
|Parameter used to set the database URL so that SOGo can store and
retrieve secured user sessions information. For PostgreSQL, the database
URL could be set to something like:
`postgresql://sogo:sogo@localhost:5432/sogo/sogo_sessions_folder`.
`postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_sessions_folder`.
|S |OCSEMailAlarmsFolderURL
|Parameter used to set the database URL for email-based alarms (that can
be set on events and tasks). This parameter is relevant only if
_SOGoEnableEMailAlarms_ is set to `YES`. For PostgreSQL, the database
URL could be set to something like:
`postgresql://sogo:sogo@localhost:5432/sogo/sogo_alarms_folder`
`postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_alarms_folder`
|S |OCSStoreURL
|Parameter used to set the database URL so that SOGo can use to store
@@ -1474,7 +1488,7 @@ a total of nine database tables - and prevent SOGo from creating three
database tables per collection.
For PostgresSQL, set the database URL to something like:
`postgresql://sogo:@localhost:5432/sogo/sogo_store`.
`postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_store`.
|S |OCSAclURL
|Parameter used to set the database URL so that SOGo can use to store
@@ -1482,7 +1496,7 @@ all ACL data. You must also set `OCSStoreURL` and `OCSCacheFolderURL`
if you set this parameter.
For PostgresSQL, set the database URL to something like:
`postgresql://sogo:@localhost:5432/sogo/sogo_acl`.
`postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_acl`.
|S |OCSCacheFolderURL
|Parameter used to set the database URL so that SOGo can use to store
@@ -1490,7 +1504,7 @@ all cache data. You must also set `OCSStoreURL` and `OCSAclURL`
if you set this parameter.
For PostgresSQL, set the database URL to something like:
`postgresql://sogo:@localhost:5432/sogo/sogo_cache_folder`.
`postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_cache_folder`.
See the "EMail reminders" section in this document for more information.
|=======================================================================
@@ -1596,9 +1610,9 @@ configuration is very similar to LDAP-based authentication.
The following table describes all the possible parameters related to a
SQL source:
[cols="3,47,50a"]
[cols="3,47a,50"]
|=======================================================================
.18+|D |SOGoUserSources
.18+^|D |SOGoUserSources
|Parameter used to set the SQL and/or LDAP sources used for
authentication and global address books. Multiple sources can be
specified as an array of dictionaries. A dictionary that defines a SQL
@@ -1839,17 +1853,17 @@ used by SOGo. You can also use SSL or TLS by providing a value using an
URL, such as:
[options="compact"]
* `imaps://localhost:993`
* `imaps://localhost:143/?tls=YES`
* `imaps://127.0.0.1:993`
* `imap://127.0.0.1:143/?tls=YES`
|D |SOGoSieveServer
|Parameter used to set the DNS name or IP address of the Sieve
(managesieve) server used by SOGo. You must use an URL such as:
[options="compact"]
* `sieve://localhost`
* `sieve://localhost:2000`
* `sieve://localhost:2000/?tls=YES`
* `sieve://127.0.0.1`
* `sieve://127.0.0.1:2000`
* `sieve://127.0.0.1:2000/?tls=YES`
Note that TLS is supported but SSL is not.
@@ -2354,11 +2368,11 @@ like this:
----
{
SOGoProfileURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_user_profile";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_user_profile";
OCSFolderInfoURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_folder_info";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_folder_info";
OCSSessionsFolderURL =
"postgresql://sogo:sogo@localhost:5432/sogo/sogo_sessions_folder";
"postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_sessions_folder";
SOGoAppointmentSendEMailNotifications = YES;
SOGoCalendarDefaultRoles = (
PublicViewer,
@@ -2367,7 +2381,7 @@ like this:
SOGoLanguage = English;
SOGoTimeZone = America/Montreal;
SOGoMailDomain = acme.com;
SOGoIMAPServer = localhost;
SOGoIMAPServer = 127.0.0.1;
SOGoDraftsFolderName = Drafts;
SOGoSentFolderName = Sent;
SOGoTrashFolderName = Trash;
@@ -2385,7 +2399,7 @@ like this:
bindPassword = qwerty;
canAuthenticate = YES;
displayName = "Shared Addresses";
hostname = localhost;
hostname = 127.0.0.1;
id = public;
isAddressBook = YES;
port = 389;
@@ -2421,7 +2435,7 @@ coyote.com):
bindPassword = qwerty;
canAuthenticate = YES;
displayName = "Shared Addresses";
hostname = localhost;
hostname = 127.0.0.1;
id = public_acme;
isAddressBook = YES;
port = 389;
@@ -2442,7 +2456,7 @@ coyote.com):
bindPassword = qwerty;
canAuthenticate = YES;
displayName = "Shared Addresses";
hostname = localhost;
hostname = 127.0.0.1;
id = public_coyote;
isAddressBook = YES;
port = 389;
@@ -2612,7 +2626,7 @@ Load the LDIF file inside your LDAP server using the following command:
Finally, set the password (to the value `qwerty`) of the SOGo
administrative account using the following command:
ldappasswd -h localhost -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=sogo,ou=users,dc=acme,dc=com -s qwerty
ldappasswd -h 127.0.0.1 -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=sogo,ou=users,dc=acme,dc=com -s qwerty
Creating a User Account
~~~~~~~~~~~~~~~~~~~~~~~
@@ -2640,7 +2654,7 @@ Load the LDIF file inside your LDAP server using the following command:
Finally, set the password (to the value `qwerty`) of the SOGo
administrative account using the following command:
ldappasswd -h localhost -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=jdoe,ou=users,dc=acme,dc=com -s qwerty
ldappasswd -h 127.0.0.1 -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=jdoe,ou=users,dc=acme,dc=com -s qwerty
As an alternative to using command-line tools, you can also use LDAP
editors such as _Luma_ or _Apache Directory Studio_ to make your work
@@ -2720,13 +2734,19 @@ have unexpected behaviour with various ActiveSync clients.
EAS command.
Defaults to `NO`, which means no logging is performed.
|S |SOGoMaximumPictureSize
|Parameter used to overwrite the maximum number of bytes returned in the picture
for EAS Search operations in the GAL.
If not set, it defaults to `102400` bytes, or 100 KB.
|=======================================================================
Please be aware of the following limitations:
* Outlook 2013 does not search the GAL. One possible alternative
* Outlook 2013/2016 does not search the GAL. One possible alternative
solution is to configure Outlook to use a LDAP server (over SSL) with
authentication. Outlook 2013 also does not seem to support multiple
authentication. Outlook 2013/2016 also does not seem to support multiple
address books over ActiveSync.
* To successfully synchronize Outlook email categories, a corresponding
mail label (Preferences->Mail Options) has to be created manually in SOGo
@@ -2742,9 +2762,9 @@ to handle many clients. Make sure you tune your SOGo server when having
lots of ActiveSync clients.
* Repetitive events with occurrences exceptions are currently not
supported.
* Outlook 2013 Autodiscovery is currently not supported.
* Outlook 2013 freebusy lookups are supported using the Internet
Free/Busy feature of Outlook 2013. Please
* Outlook 2013/2016 Autodiscovery is currently not supported.
* Outlook 2013/2016 freebusy lookups are supported using the Internet
Free/Busy feature of Outlook 2013/2016. Please
see http://support.microsoft.com/kb/291621 for configuration
instructions. On the SOGo side, _SOGoEnablePublicAccess_ must be set to
`YES` and the URL to use must be of the following format:
@@ -2753,6 +2773,9 @@ instructions. On the SOGo side, _SOGoEnablePublicAccess_ must be set to
need to adjust the word size of your IMAP server. In Dovecot, the parameter
to increase is "imap_max_line_length" while under Cyrus IMAP Server, the
parameter is "maxword". We suggest a buffer of 2MB.
* If you are using MySQL, make sure you set "max_allowed_packet" to a large value
since the EAS cache size can be large for mailboxes with thousands of messages.
A 64M or even 128M value is recommended.
In order to use the SOGo ActiveSync support code in production
environments, you need to get a proper usage license from Microsoft.
@@ -2853,7 +2876,7 @@ SOGo Web Interface
To acces the SOGo Web Interface, point your Web browser, which is
running from the same server where SOGo was installed, to the following
URL: http://localhost/SOGo.
URL: http://127.0.0.1/SOGo.
Log in using the "jdoe" user and the "qwerty" password. The underlying
database tables will automatically be created by SOGo.
@@ -2888,7 +2911,7 @@ To access your personal address book:
* Choose File > New > Remote Address Book.
* Enter a significant name for your calendar in the Name field.
* Type the following URL in the URL field:
`http://localhost/SOGo/dav/jdoe/Contacts/personal/`
`http://127.0.0.1/SOGo/dav/jdoe/Contacts/personal/`
* Click on OK.
To access your personal calendar:
@@ -2898,20 +2921,21 @@ To access your personal calendar:
* Select On the Network and click on Continue.
* Select CalDAV.
* Type the following URL in the URL field:
`http://localhost/SOGo/dav/jdoe/Calendar/personal/`
`http://127.0.0.1/SOGo/dav/jdoe/Calendar/personal/`
* Click on Continue.
Apple iCal
~~~~~~~~~~
Apple Calendar and iOS
~~~~~~~~~~~~~~~~~~~~~~
Apple iCal can also be used as a client application for SOGo.
Apple Calendar and Mac OS X and the calendar application on iOS can also be used
as a client application for SOGo.
To configure it so it works with SOGo, create a new account and specify,
To configure the application so it works with SOGo, create a new account and specify,
as the Account URL, an URL such as:
http://localhost/SOGo/dav/jdoe/
http://127.0.0.1/SOGo/dav/jdoe/
Note that the trailing slash is important for Apple iCal 3.
Note that the trailing slash is important for the old Apple iCal 3 application.
Apple AddressBook
~~~~~~~~~~~~~~~~~
@@ -2964,7 +2988,7 @@ any mobile devices that support Microsoft ActiveSync. Microsoft Outlook
2013 is also supported.
The Microsoft ActiveSync server URL is generally something
like: `http://localhost/Microsoft-Server-ActiveSync`.
like: `http://127.0.0.1/Microsoft-Server-ActiveSync`.
Upgrading
---------
+2 -2
View File
@@ -121,9 +121,9 @@
</xsl:choose>
</xsl:template>
<xsl:template name="next.itemsymbol">
<xsl:param name="itemsymbol" select="'default'"/>
<xsl:param name="itemsymbol" select="'square'"/>
<xsl:choose>
<xsl:otherwise>square</xsl:otherwise>
<xsl:when test="$itemsymbol='square'">square</xsl:when>
</xsl:choose>
</xsl:template>
+3 -3
View File
@@ -1,7 +1,7 @@
<!-- TODO have the build system take care of this -->
<releaseinfo>Version 3.2.2 - November 2016</releaseinfo>
<subtitle>for version 3.2.2</subtitle>
<date>2016-11-23</date>
<releaseinfo>Version 3.2.10 - July 2017</releaseinfo>
<subtitle>for version 3.2.10</subtitle>
<date>2017-07-05</date>
<legalnotice>
<para>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".</para>
@@ -6,7 +6,7 @@
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2008-2016 Inverse inc.
Copyright (C) 2008-2017 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
////
@@ -6,13 +6,13 @@
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2008-2016 Inverse inc.
Copyright (C) 2008-2017 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
////
// TODO have the build system take care of this
:release_version: 3.2.2
:release_version: 3.2.10
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
+1 -1
View File
@@ -6,7 +6,7 @@
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2008-2014 Inverse inc.
Copyright (C) 2008-2017 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
////
+16 -5
View File
@@ -27,6 +27,7 @@
#import <GDLContentStore/GCSAlarmsFolder.h>
#import <GDLContentStore/GCSSessionsFolder.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoClassSecurityInfo.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest+So.h>
@@ -114,7 +115,7 @@ static BOOL debugLeaks;
vMemSizeLimit = [defaults vmemLimit];
if (vMemSizeLimit > 0)
[self logWithFormat: @"vmem size check enabled: shutting down app when "
@"vmem > %d MB", vMemSizeLimit];
@"vmem > %d MB. Currently at %d MB", vMemSizeLimit, [[NSProcessInfo processInfo] virtualMemorySize]/1048576];
/* SoClass security declarations */
sInfo = [self soClassSecurityInfo];
@@ -137,6 +138,8 @@ static BOOL debugLeaks;
/* load products */
[[SOGoProductLoader productLoader] loadAllProducts: YES];
if (vMemSizeLimit > 0)
[self logWithFormat: @"All products loaded - current memory usage at %d MB", [[NSProcessInfo processInfo] virtualMemorySize]/1048576];
}
- (id) init
@@ -418,8 +421,12 @@ static BOOL debugLeaks;
"GET" if no method was provided in the query path.
*/
if ([_key length] > 0 && ![_key isEqualToString:@"favicon.ico"])
obj = [self lookupUser: _key inContext: _ctx];
}
{
obj = [self lookupUser: _key inContext: _ctx];
if (!obj && ![_key isEqualToString: @"public"])
obj = [self lookupUser: @"anonymous" inContext: _ctx];
}
}
}
else
obj = nil;
@@ -445,8 +452,12 @@ static BOOL debugLeaks;
- (WOResponse *) handleException: (NSException *) _exc
inContext: (WOContext *) _ctx
{
printf("EXCEPTION: %s\n", [[_exc description] cString]);
abort();
WOResponse *resp;
NSLog(@"EXCEPTION: %s\n", [[_exc description] cString]);
resp = [WOResponse responseWithRequest: [_ctx request]];
[resp setStatus: 501];
return resp;
}
/* runtime maintenance */
+235 -1
View File
@@ -1,10 +1,244 @@
3.2.10 (2017-07-05)
-------------------
New features
- [web] new images viewer in Mail module
- [web] create list from selected cards (#3561)
- [eas] initial EAS v16 and email drafts support
- [core] load-testing scripts to evaluate SOGo performance
Enhancements
- [core] now possible to {un}subscribe to folders using sogo-tool
- [web] AngularJS optimizations in Mail module
- [web] AngularJS optimization of color picker
- [web] improve display of tasks status
- [web] added custom fields support from Thunderbird's address book
- [web] added Latvian (lv) translation - thanks to Juris Balandis
- [web] expose user's defaults and settings inline
- [web] can now discard incoming mails during vacation
- [web] support both backspace and delete keys in Mail and Contacts modules
- [web] improved display of appointment/task comments and card notes
- [web] updated Angular Material to version 1.1.4
- [web] updated CKEditor to version 4.7.1
Bug fixes
- [web] respect SOGoLanguage and SOGoSupportedLanguages (#4169)
- [web] fixed adding list members with multiple email addresses
- [web] fixed responsive condition of login page (960px to 1023px)
- [web] don't throw errors when accessing nonexistent special mailboxes (#4177)
- [core] newly subscribed calendars are excluded from freebusy (#3354)
- [core] don't update subscriptions when owner is not the active user (#3988)
- [core] strip cr during LDIF import process (#4172)
- [core] email alarms are sent too many times (#4100)
- [core] enable S/MIME even when using GNU TLS (#4201)
- [core] silence verbose output for sogo-ealarms-notify (#4170)
- [eas] don't include task folders if we hide them in SOGo (#4164)
3.2.9 (2017-05-09)
------------------
New features
- [core] email alarms now have pretty formatting (#805)
Enhancements
- [core] improved event invitation for all day events (#4145)
- [web] improved interface refresh time with external IMAP accounts
- [eas] added photo support for GAL search operations
Bug fixes
- [web] fixed attachment path when inside multiple body parts
- [web] fixed email reminder with attendees (#4115)
- [web] prevented form to be marked dirty when changing password (#4138)
- [web] restored support for SOGoLDAPContactInfoAttribute
- [web] avoid duplicated email addresses in LDAP-based addressbook (#4129)
- [web] fixed mail delegation of pristine user accounts (#4160)
- [core] cherry-picked comma escaping fix from v2 (#3296)
- [core] fix sogo-tool restore potentially crashing on corrupted data (#4048)
- [core] handle properly mails using windows-1255 charset (#4124)
- [core] fixed email reminders sent multiple times (#4100)
- [core] fixed LDIF to vCard conversion for non-handled multi-value attributes (#4086)
- [core] properly honor the "include in freebusy" setting (#3354)
- [core] make sure to use crypt scheme when encoding md5/sha256/sha512 (#4137)
- [eas] set reply/forwarded flags when ReplaceMime is set (#4133)
- [eas] remove alarms over EAS if we don't want them (#4059)
- [eas] correctly set RSVP on event invitations
- [eas] avoid sending IMIP request/update messages for all EAS clients (#4022)
3.2.8 (2017-03-24)
------------------
New features
- [core] new sogo-tool manage-acl command to manage calendar/address book ACLs
Enhancements
- [web] constrain event/task reminder to a positive number
- [web] display year in day and week views
- [web] split string on comma and semicolon when pasting multiple addresses (#4097)
- [web] restrict Draft/Sent/Trash/Junk mailboxes to the top level
- [web] animations are automatically disabled under IE11
- [web] updated Angular Material to version 1.1.3
Bug fixes
- [core] handle broken CalDAV clients sending bogus SENT-BY (#3992)
- [core] fixed handling of exdates and proper intersection for fbinfo (#4051)
- [core] remove attendees that have the same identity as the organizer (#3905)
- [web] fixed ACL editor in admin module for Safari (#4036)
- [web] fixed function call when removing contact category (#4039)
- [web] localized mailbox names everywhere (#4040, #4041)
- [web] hide fab button when printing (#4038)
- [web] SOGoCalendarWeekdays must now be defined before saving preferences
- [web] fixed CAS session timeout handling during XHR requests (#1456)
- [web] exposed default value of SOGoMailAutoSave (#4053)
- [web] exposed default value of SOGoMailAddOutgoingAddresses (#4064)
- [web] fixed handling of contact organizations (#4028)
- [web] fixed handling of attachments in mail editor (#4058, #4063)
- [web] fixed saving draft outside Mail module (#4071)
- [web] fixed SCAYT automatic language selection in HTML editor
- [web] fixed task sorting on multiple categories
- [web] fixed sanitisation of flags in Sieve filters (#4087)
- [web] fixed missing CC or BCC when specified before sending message (#3944)
- [web] enabled Save button after deleting attributes from a card (#4095)
- [web] don't show Copy To and Move To menu options when user has a single address book
- [web] fixed display of category colors in events and tasks lists
- [eas] fixed opacity in EAS freebusy (#4033)
3.2.7 (2017-02-14)
------------------
New features
- [core] new sogo-tool checkup command to make sure user's data is sane
Enhancements
- [web] added Hebrew (he) translation - thanks to Raz Aidlitz
Bug fixes
- [core] generalized the bcc handling code
- [web] saving the preferences was not possible when Mail module is disabled
- [web] ignore mouse events in scrollbars of Month view (#3990)
- [web] fixed public URL with special characters (#3993)
- [web] keep the fab button visible when the center list is hidden
- [web] localized mail, phone, url and address types (#4030)
- [eas] improved EAS parameters parsing (#4003)
- [eas] properly handle canceled appointments
3.2.6a (2017-01-26)
-------------------
Bug fixes
- [core] fixed "include in freebusy" (reverts #3354)
- [web] improved ACLs handling of inactive users
3.2.6 (2017-01-23)
------------------
Enhancements
- [web] show locale codes beside language names in Preferences module
- [web] fixed visual glitches in Month view with Firefox
- [web] mail editor can now be expanded horizontally and automatically expands vertically
- [web] compose a new message inline or in a popup window
- [web] allow to select multiple files when uploading attachments (#3999)
- [web] use "date" extension of Sieve to enable/disable vacation auto-reply (#1530, #1949)
- [web] updated Angular to version 1.6.1
- [web] updated CKEditor to version 4.6.2
Bug fixes
- [core] remove all alarms before sending IMIP replies (#3925)
- [web] fixed rendering of forwared HTML message with inline images (#3981)
- [web] fixed pasting images in CKEditor using Chrome (#3986)
- [eas] make sure we trigger a download of service-side changed events
- [eas] now strip attendees with no email during MeetingResponse calls
3.2.5 (2017-01-10)
------------------
New features
- [web] download attachments of a message as a zip archive
Enhancements
- [core] improved IMIP handling from Exchange/Outlook clients
- [web] prevent using localhost on additional IMAP accounts
- [web] renamed buttons of alarm toast (#3945)
- [web] load photos of LDAP-based address books in contacts list (#3942)
- [web] added SOGoMaximumMessageSizeLimit to limit webmail message size
- [web] added photo support for LDIF import (#1084)
- [web] updated CKEditor to version 4.6.1
Bug fixes
- [core] honor blocking wrong login attempts within time interval (#2850)
- [core] better support for RFC 6638 (schedule-agent)
- [core] use source's domain when none defined and trying to match users (#3523)
- [core] handle delegation with no SENT-BY set (#3368)
- [core] properly honor the "include in freebusy" setting (#3354)
- [core] properly save next email alarm in the database (#3949)
- [core] fix events in floating time during CalDAV's PUT operation (#2865)
- [core] handle rounds in sha512-crypt password hashes
- [web] fixed confusion between owner and active user in ACLs management of Administration module
- [web] fixed JavaScript exception after renaming an address book
- [web] fixed Sieve folder encoding support (#3904)
- [web] fixed ordering of calendars when renaming or adding a calendar (#3931)
- [web] use the organizer's alarm by default when accepting IMIP messages (#3934)
- [web] switch on "Remember username" when cookie username is set
- [web] return login page for unknown users (#2135)
- [web] fixed saving monthly recurrence rule with "by day" condition (#3948)
- [web] fixed display of message content when enabling auto-reply (#3940)
- [web] don't allow to create lists in a remote address book (not yet supported)
- [web] fixed attached links in task viewer (#3963)
- [web] avoid duplicate mail entries in contact of LDAP-based address book (#3941)
- [web] append ics file extension when importing events (#2308)
- [web] handle URI in vCard photos (#2683)
- [web] handle semicolon in values during LDIF import (#1760)
- [web] fixed computation of week number (#3973, #3976)
- [web] fixed saving of inactive calendars (#3862, #3980)
- [web] fixed public URLs to Calendars (#3974)
- [web] fixed hotkeys in Mail module when a dialog is active (#3983)
- [eas] properly skip folders we don't want to synchronize (#3943)
- [eas] fixed 30 mins freebusy offset with S Planner
- [eas] now correctly handles reminders on tasks (#3964)
- [eas] always force save events creation over EAS (#3958)
- [eas] do not decode from hex the event's UID (#3965)
- [eas] add support for "other addresses" (#3966)
- [eas] provide correct response status when sending too big mails (#3956)
3.2.4 (2016-12-01)
------------------
New features
- [core] new sogo-tool cleanup user feature
Enhancements
- [core] added handling of BYSETPOS for BYDAY in recurrence rules
- [web] added sort by start date for tasks (#3840)
Bug fixes
- [web] fixed JavaScript exception when SOGo is launched from an external link (#3900)
- [web] restored fetching of freebusy information of MS Exchange contacts
- [web] fixed mail attribute when importing an LDIF file (#3878)
- [web] don't save empty custom auto-reply subject
- [web] fixed detection of session expiration
- [eas] properly escape all GAL responses (#3923)
3.2.3 (2016-11-25)
------------------
New features
- [core] added photo support for LDAP-based address books (#747, #2184)
Enhancements
- [web] updated CKEditor to version 4.6.0
- [web] updated Angular to version 1.5.9
Bug fixes
- [web] restore attributes when rewriting base64-encoded img tags (#3814)
- [web] improve alarms dialog (#3909)
- [eas] fixed EAS delete operation
3.2.2 (2016-11-23)
------------------
New features
- [core] support repetitive email alarms on tasks and events (#1053)
- [web] allow to hide center column on large screens (#3861)
- [eas] relaxed permission requirements for subscription synchronizations (#3118 and #3180)
- [eas] relaxed permission requirements for subscription synchronizations (#3118, #3180)
Enhancements
- [core] added sha256-crypt and sha512-crypt password support
+2
View File
@@ -45,9 +45,11 @@ SOGo and its associated components are available in various languages. The follo
* [fi] Finnish - Kari Salmu
* [fr] French - [Inverse](http://www.inverse.ca/)
* [de] German - Alexander Greiner-Baer
* [he] Hebrew - Raz Aidlitz
* [hu] Hungarian - Sándor Kuti
* [is] Icelandic - Anna Jonna Armannsdottir
* [it] Italian - Alessio Fattorini
* [lv] Latvian - Juris Balandis
* [lt] Lithuanian - Mantas Liobė
* [mk_MK] Macedonian - Miroslav Jovanovic
* [nb_NO] Norwegian (Bokmål) - Jan Ivar Karlsen
+2
View File
@@ -123,6 +123,7 @@
- (NSException *) deleteContentWithName: (NSString *) _name;
- (NSException *) deleteAllContent;
- (NSException *) purgeDeletedRecordsBefore: (unsigned int) days;
- (NSException *) touchContentWithName: (NSString *) _name;
- (NSException *) deleteFolder;
@@ -144,6 +145,7 @@
- (void) deleteAclWithSpecification: (EOFetchSpecification *) _fs;
- (unsigned int) recordsCountByExcludingDeleted: (BOOL) includeDeleted;
- (unsigned int) recordsCountDeletedBefore: (unsigned int) days;
- (NSCalendarDate *) lastModificationDate;
+163 -70
View File
@@ -68,7 +68,7 @@ static GCSStringFormatter *stringFormatter = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
debugOn = [ud boolForKey:@"GCSFolderDebugEnabled"];
doLogStore = [ud boolForKey:@"GCSFolderStoreDebugEnabled"];
@@ -91,7 +91,7 @@ static GCSStringFormatter *stringFormatter = nil;
NSEnumerator *fields;
GCSFieldInfo *field;
NSString *fieldName;
if ((self = [super init])) {
folderManager = [_fm retain];
folderInfo = [_ftype retain];
@@ -114,7 +114,7 @@ static GCSStringFormatter *stringFormatter = nil;
if (![fieldName isEqualToString: @"c_name"])
[contentFieldNames addObject: fieldName];
}
folderId = [_folderId copy];
folderName = [[_path lastPathComponent] copy];
path = [_path copy];
@@ -124,7 +124,7 @@ static GCSStringFormatter *stringFormatter = nil;
folderTypeName = [_ftname copy];
ofFlags.requiresFolderSelect = 0;
ofFlags.sameTableForQuick =
ofFlags.sameTableForQuick =
[location isEqualTo:quickLocation] ? 1 : 0;
}
return self;
@@ -133,7 +133,7 @@ static GCSStringFormatter *stringFormatter = nil;
- (id) init
{
return [self initWithPath:nil primaryKey:nil
folderTypeName:nil folderType:nil
folderTypeName:nil folderType:nil
location:nil quickLocation:nil
aclLocation:nil
folderManager:nil];
@@ -271,13 +271,13 @@ static GCSStringFormatter *stringFormatter = nil;
NSDictionary *ui;
ui = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithUnsignedInt:_base],
[NSNumber numberWithUnsignedInt:_base],
@"GCSExpectedVersion",
[NSNumber numberWithUnsignedInt:_store],
@"GCSStoredVersion",
self, @"GCSFolder",
nil];
return [NSException exceptionWithName:@"GCSVersionMismatch"
reason:@"Transaction conflict during a GCS modification."
userInfo:ui];
@@ -369,7 +369,7 @@ static GCSStringFormatter *stringFormatter = nil;
requirement: (GCSTableRequirement) requirement
{
NSString *selectedFields;
if (requirement == bothTableRequired && [fields containsObject: @"c_name"])
selectedFields = [self _dottedFields: fields];
else
@@ -381,7 +381,7 @@ static GCSStringFormatter *stringFormatter = nil;
- (NSString *) _sqlForQualifier: (EOQualifier *) qualifier
{
NSMutableString *ms;
if (qualifier)
{
ms = [NSMutableString stringWithCapacity:32];
@@ -399,7 +399,7 @@ static GCSStringFormatter *stringFormatter = nil;
if ((count = [_so count]) == 0)
return nil;
sql = [NSMutableString stringWithCapacity:(count * 16)];
for (i = 0; i < count; i++) {
EOSortOrdering *so;
@@ -409,9 +409,9 @@ static GCSStringFormatter *stringFormatter = nil;
so = [_so objectAtIndex:i];
sel = [so selector];
column = [so key];
if (i > 0) [sql appendString:@", "];
if (sel_eq(sel, EOCompareAscending)) {
[sql appendString:column];
[sql appendString:@" ASC"];
@@ -558,21 +558,21 @@ static GCSStringFormatter *stringFormatter = nil;
error = [channel evaluateExpressionX:sql];
if (error)
{
[self errorWithFormat:@"%s: cannot execute quick-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute quick-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
results = nil;
}
else
{
/* fetch results */
results = [NSMutableArray arrayWithCapacity: 64];
attrs = [channel describeResults: NO /* do not beautify names */];
while ((row = [channel fetchAttributes: attrs withZone: NULL]))
[results addObject: row];
/* release channels */
}
[self releaseChannel: channel];
// NSLog(@"/running query");
@@ -582,7 +582,7 @@ static GCSStringFormatter *stringFormatter = nil;
[self errorWithFormat:@" could not open storage channel!"];
results = nil;
}
return results;
}
@@ -764,7 +764,7 @@ andAttribute: (EOAttribute *)_attribute
EOAttribute *attribute;
id value;
unsigned i, count;
if (_row == nil || _table == nil)
return nil;
@@ -774,7 +774,7 @@ andAttribute: (EOAttribute *)_attribute
[sql appendString:@"UPDATE "];
[sql appendString:_table];
[sql appendString:@" SET "];
for (i = 0, count = [keys count]; i < count; i++) {
fieldName = [keys objectAtIndex:i];
@@ -823,7 +823,7 @@ andAttribute: (EOAttribute *)_attribute
{
EOAttribute *attribute;
EOEntity *entity;
entity = AUTORELEASE([[EOEntity alloc] init]);
[entity setName: _name];
[entity setExternalName: _name];
@@ -841,7 +841,7 @@ andAttribute: (EOAttribute *)_attribute
EOAttribute *attribute;
EOEntity *entity;
entity = [self _entityWithName: [self storeTableName]];
entity = [self _entityWithName: [self storeTableName]];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: @"c_version"];
@@ -873,7 +873,7 @@ andAttribute: (EOAttribute *)_attribute
- (EOSQLQualifier *) _qualifierUsingWhereColumn:(NSString *)_colname
isEqualTo:(id)_value
andColumn:(NSString *)_colname2
andColumn:(NSString *)_colname2
isEqualTo:(id)_value2
entity: (EOEntity *)_entity
withAdaptor: (EOAdaptor *)_adaptor
@@ -970,7 +970,7 @@ andAttribute: (EOAttribute *)_attribute
NSArray *rows;
NSException *error;
/* check preconditions */
/* check preconditions */
if (_name)
{
if (_content)
@@ -979,10 +979,10 @@ andAttribute: (EOAttribute *)_attribute
error = nil;
nowDate = [NSCalendarDate date];
now = [NSNumber numberWithUnsignedInt:[nowDate timeIntervalSince1970]];
if (doLogStore)
[self logWithFormat:@"should store content: '%@'\n%@", _name, _content];
rows = [self fetchFields: [NSArray arrayWithObjects:
@"c_version",
@"c_deleted",
@@ -1021,6 +1021,7 @@ andAttribute: (EOAttribute *)_attribute
NSInvocation *anInvocation;
SEL aSelector;
quickRow = nil;
aSelector = @selector(quickRecordFromContent:container:nameInContainer:);
aSignature = [[theComponent class] instanceMethodSignatureForSelector: aSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
@@ -1035,16 +1036,16 @@ andAttribute: (EOAttribute *)_attribute
if (quickRow)
{
[quickRow setObject:_name forKey:@"c_name"];
if (doLogStore)
[self logWithFormat:@" store quick: %@", quickRow];
/* make content row */
contentRow = [NSMutableDictionary dictionaryWithCapacity:16];
if (ofFlags.sameTableForQuick)
[contentRow addEntriesFromDictionary:quickRow];
[contentRow setObject:_name forKey:@"c_name"];
[contentRow setObject:now forKey:@"c_lastmodified"];
if (isNewRecord)
@@ -1058,7 +1059,7 @@ andAttribute: (EOAttribute *)_attribute
[NSNumber numberWithInt:([storedVersion intValue] + 1)]
forKey:@"c_version"];
[contentRow setObject:_content forKey:@"c_content"];
/* open channels */
storeChannel = [self acquireStoreChannel];
if (storeChannel)
@@ -1080,14 +1081,14 @@ andAttribute: (EOAttribute *)_attribute
/* we check if we can call directly methods on our adaptor
channel delegate. If not, we generate SQL ourself since it'll
be a little bit faster and less complex than using GDL to do so */
hasInsertDelegate = [[storeChannel delegate]
hasInsertDelegate = [[storeChannel delegate]
respondsToSelector: @selector(adaptorChannel:willInsertRow:forEntity:)];
hasUpdateDelegate = [[storeChannel delegate]
respondsToSelector: @selector(adaptorChannel:willUpdateRow:describedByQualifier:)];
[[quickChannel adaptorContext] beginTransaction];
[[storeChannel adaptorContext] beginTransaction];
quickTableEntity = [self _quickTableEntity];
storeTableEntity = [self _storeTableEntity];
@@ -1097,10 +1098,10 @@ andAttribute: (EOAttribute *)_attribute
error = (hasInsertDelegate
? [quickChannel insertRowX: quickRow forEntity: quickTableEntity]
: [quickChannel
evaluateExpressionX: [self _generateInsertStatementForRow: quickRow
evaluateExpressionX: [self _generateInsertStatementForRow: quickRow
adaptor: [[quickChannel adaptorContext] adaptor]
tableName: [self quickTableName]]]);
if (!error)
error = (hasInsertDelegate
? [storeChannel insertRowX: contentRow forEntity: storeTableEntity]
@@ -1138,7 +1139,7 @@ andAttribute: (EOAttribute *)_attribute
andColumn: (*_baseVersion != 0 ? (id)@"c_version" : (id)nil)
isEqualTo: (*_baseVersion != 0 ? [NSNumber numberWithUnsignedInt: *_baseVersion] : (NSNumber *)nil)]]);
}
if (error)
{
[[storeChannel adaptorContext] rollbackTransaction];
@@ -1193,19 +1194,19 @@ andAttribute: (EOAttribute *)_attribute
NSException *error;
NSString *delsql;
NSCalendarDate *nowDate;
/* check preconditions */
if (_name == nil) {
return [NSException exceptionWithName:@"GCSDeleteException"
reason:@"no content filename was provided"
userInfo:nil];
}
if (doLogStore)
[self logWithFormat:@"should delete content: '%@'", _name];
/* open channels */
if ((storeChannel = [self acquireStoreChannel]) == nil) {
[self errorWithFormat:@"could not open storage channel!"];
return nil;
@@ -1242,7 +1243,7 @@ andAttribute: (EOAttribute *)_attribute
delsql = [delsql stringByAppendingFormat:@" AND c_folder_id = %@", folderId];
if ((error = [storeChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat:
@"%s: cannot delete content '%@': %@",
@"%s: cannot delete content '%@': %@",
__PRETTY_FUNCTION__, delsql, error];
}
else if (!ofFlags.sameTableForQuick) {
@@ -1256,19 +1257,19 @@ andAttribute: (EOAttribute *)_attribute
delsql = [delsql stringByAppendingFormat:@" AND c_folder_id = %@", folderId];
if ((error = [quickChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat:
@"%s: cannot delete quick row '%@': %@",
@"%s: cannot delete quick row '%@': %@",
__PRETTY_FUNCTION__, delsql, error];
/*
/*
Note: we now have a "broken" record, needs to be periodically GCed by
a script!
*/
}
}
/* release channels and return */
[adaptorCtx commitTransaction];
[self releaseChannel:storeChannel];
if (!ofFlags.sameTableForQuick) {
[[quickChannel adaptorContext] commitTransaction];
[self releaseChannel:quickChannel];
@@ -1307,7 +1308,7 @@ andAttribute: (EOAttribute *)_attribute
query = [NSString stringWithFormat: @"DELETE FROM %@", [self storeTableName]];
error = [storeChannel evaluateExpressionX:query];
if (error)
[self errorWithFormat: @"%s: cannot delete content '%@': %@",
[self errorWithFormat: @"%s: cannot delete content '%@': %@",
__PRETTY_FUNCTION__, query, error];
else if (!ofFlags.sameTableForQuick) {
/* content row deleted, now delete the quick row */
@@ -1317,7 +1318,7 @@ andAttribute: (EOAttribute *)_attribute
query = [NSString stringWithFormat: @"DELETE FROM %@", [self quickTableName]];
error = [quickChannel evaluateExpressionX: query];
if (error)
[self errorWithFormat: @"%s: cannot delete quick row '%@': %@",
[self errorWithFormat: @"%s: cannot delete quick row '%@': %@",
__PRETTY_FUNCTION__, query, error];
}
@@ -1333,6 +1334,49 @@ andAttribute: (EOAttribute *)_attribute
return error;
}
- (NSException *) purgeDeletedRecordsBefore: (unsigned int) days
{
NSString *delSql, *table;
EOAdaptorContext *adaptorCtx;
EOAdaptorChannel *channel;
NSCalendarDate *nowDate;
unsigned int delta;
channel = [self acquireStoreChannel];
if ((channel = [self acquireStoreChannel]) == nil)
return [NSException exceptionWithName: @"GCSChannelException"
reason: @"could not open storage channel!"
userInfo: nil];
adaptorCtx = [channel adaptorContext];
[adaptorCtx beginTransaction];
table = [self storeTableName];
nowDate = [NSCalendarDate date];
delta = days * 24 * 60 * 60;
if (delta > [nowDate timeIntervalSince1970])
return [NSException exceptionWithName: @"GCSArgumentException"
reason: @"number of days is too high!"
userInfo: nil];
delta = [nowDate timeIntervalSince1970] - delta;
if ([GCSFolderManager singleStoreMode])
delSql = [NSString stringWithFormat: @"DELETE FROM %@"
@" WHERE c_folder_id = %@ AND c_deleted = 1 AND c_lastmodified < %u",
table, folderId, delta];
else
delSql = [NSString stringWithFormat: @"DELETE FROM %@"
@" WHERE c_deleted = 1 AND c_lastmodified < %u",
table, delta];
[channel evaluateExpressionX: delSql];
[[channel adaptorContext] commitTransaction];
[self releaseChannel: channel];
return nil;
}
- (NSException *) touchContentWithName: (NSString *) _name
{
NSString *touchSql, *table;
@@ -1389,14 +1433,14 @@ andAttribute: (EOAttribute *)_attribute
EOAdaptorChannel *channel;
NSString *delsql;
NSString *table;
/* open channels */
if ((channel = [self acquireStoreChannel]) == nil) {
[self errorWithFormat:@"could not open channel!"];
return nil;
}
/* delete rows */
[[channel adaptorContext] beginTransaction];
table = [self storeTableName];
@@ -1423,7 +1467,7 @@ andAttribute: (EOAttribute *)_attribute
delsql = [@"DROP TABLE " stringByAppendingString: table];
[channel evaluateExpressionX:delsql];
}
[[channel adaptorContext] commitTransaction];
[self releaseChannel:channel];
@@ -1437,7 +1481,7 @@ andAttribute: (EOAttribute *)_attribute
EOAdaptorChannel *quickChannel;
EOAdaptorContext *adaptorCtx;
NSException *error;
quickChannel = [self acquireQuickChannel];
adaptorCtx = [quickChannel adaptorContext];
[adaptorCtx beginTransaction];
@@ -1500,15 +1544,15 @@ andAttribute: (EOAttribute *)_attribute
NSArray *attrs;
NSMutableArray *results;
NSDictionary *row;
qualifier = [_fs qualifier];
sortOrderings = [_fs sortOrderings];
#if 0
[self logWithFormat:@"FETCH: %@", _flds];
[self logWithFormat:@" MATCH: %@", _q];
#endif
/* generate SQL */
sql = [NSMutableString stringWithCapacity:256];
@@ -1536,34 +1580,34 @@ andAttribute: (EOAttribute *)_attribute
[sql appendString:@" LIMIT "]; // count
[sql appendString:@" OFFSET "]; // index from 0
#endif
/* open channel */
if ((channel = [self acquireAclChannel]) == nil) {
[self errorWithFormat:@"could not open acl channel!"];
return nil;
}
/* run SQL */
if ((error = [channel evaluateExpressionX:sql]) != nil) {
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
[self releaseChannel:channel];
return nil;
}
/* fetch results */
results = [NSMutableArray arrayWithCapacity:64];
attrs = [channel describeResults:NO /* do not beautify names */];
while ((row = [channel fetchAttributes:attrs withZone:NULL]) != nil)
[results addObject:row];
/* release channels */
[self releaseChannel: channel];
return results;
}
@@ -1602,7 +1646,7 @@ andAttribute: (EOAttribute *)_attribute
NSException *error;
NSMutableString *sql;
NSString *qSql;
sql = [NSMutableString stringWithCapacity:256];
[sql appendString:@"DELETE FROM "];
[sql appendString:[self aclTableName]];
@@ -1620,16 +1664,16 @@ andAttribute: (EOAttribute *)_attribute
[self errorWithFormat:@"could not open acl channel!"];
return;
}
/* run SQL */
[[channel adaptorContext] beginTransaction];
if ((error = [channel evaluateExpressionX:sql]) != nil) {
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
[self releaseChannel:channel];
return;
}
[[channel adaptorContext] commitTransaction];
[self releaseChannel:channel];
}
@@ -1647,11 +1691,11 @@ andAttribute: (EOAttribute *)_attribute
if ([GCSFolderManager singleStoreMode])
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS CNT FROM %@ WHERE c_folder_id = %@",
@"SELECT COUNT(*) AS cnt FROM %@ WHERE c_folder_id = %@",
[self storeTableName], folderId];
else
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS CNT FROM %@",
@"SELECT COUNT(*) AS cnt FROM %@",
[self storeTableName]];
if (excludeDeleted)
{
@@ -1666,7 +1710,56 @@ andAttribute: (EOAttribute *)_attribute
{
error = [channel evaluateExpressionX: sqlString];
if (error)
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
__PRETTY_FUNCTION__, sqlString, error];
else
{
attrs = [channel describeResults: NO];
row = [channel fetchAttributes: attrs withZone: NULL];
count = [[row objectForKey: @"cnt"] unsignedIntValue];
[channel cancelFetch];
}
[self releaseChannel: channel];
}
return count;
}
- (unsigned int) recordsCountDeletedBefore: (unsigned int) days
{
EOAdaptorChannel *channel;
NSArray *attrs;
NSCalendarDate *nowDate;
NSDictionary *row;
NSException *error;
NSMutableString *sqlString;
unsigned int delta, count;
count = 0;
nowDate = [NSCalendarDate date];
delta = days * 24 * 60 * 60;
if (delta < [nowDate timeIntervalSince1970])
delta = [nowDate timeIntervalSince1970] - delta;
else
delta = 0;
if ([GCSFolderManager singleStoreMode])
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS cnt FROM %@"
@" WHERE c_folder_id = %@ AND c_lastmodified < %u AND c_deleted = 1",
[self storeTableName], folderId, delta];
else
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS cnt FROM %@"
@" WHERE c_lastmodified < %u AND c_deleted = 1",
[self storeTableName], delta];
channel = [self acquireStoreChannel];
if (channel)
{
error = [channel evaluateExpressionX: sqlString];
if (error)
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
__PRETTY_FUNCTION__, sqlString, error];
else
{
@@ -1716,7 +1809,7 @@ andAttribute: (EOAttribute *)_attribute
- (NSString *)description {
NSMutableString *ms;
id tmp;
ms = [NSMutableString stringWithCapacity:256];
[ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
@@ -1729,7 +1822,7 @@ andAttribute: (EOAttribute *)_attribute
if ((tmp = [self folderTypeName])) [ms appendFormat:@" type=%@", tmp];
if ((tmp = [self location]))
[ms appendFormat:@" loc=%@", [tmp absoluteString]];
[ms appendString:@">"];
return ms;
}
+1
View File
@@ -77,6 +77,7 @@
- (BOOL)folderExistsAtPath:(NSString *)_path;
- (NSArray *)listSubFoldersAtPath:(NSString *)_path recursive:(BOOL)_flag;
- (NSDictionary *) recordAtPath: (NSString *) _path;
- (GCSFolder *)folderAtPath:(NSString *)_path;
- (NSException *)createFolderOfType:(NSString *)_type withName:(NSString *)_name atPath:(NSString *)_path;
+8 -3
View File
@@ -784,7 +784,7 @@ static BOOL _singleStoreMode = NO;
return result;
}
- (GCSFolder *) folderAtPath: (NSString *) _path
- (NSDictionary *) recordAtPath: (NSString *) _path
{
NSMutableString *sql;
NSArray *fnames, *records;
@@ -841,8 +841,13 @@ static BOOL _singleStoreMode = NO;
[self debugWithFormat:@"found no record for path: '%@'", _path];
return nil;
}
return [self folderForRecord:record];
return record;
}
- (GCSFolder *) folderAtPath: (NSString *) _path
{
return [self folderForRecord: [self recordAtPath: _path]];
}
- (NSString *) baseTableNameWithUID: (NSString *) _uid
+2 -2
View File
@@ -1,6 +1,6 @@
/* CardElement.h - this file is part of SOPE
*
* Copyright (C) 2006-2014 Inverse inc.
* Copyright (C) 2006-2017 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,7 +64,7 @@
- (NSMutableDictionary *) values;
/* ELEM:...;value1,value2,...;... */
- (void) setValues: (NSMutableArray *) newValues
- (void) setValues: (id) newValues
atIndex: (NSUInteger) idx
forKey: (NSString *) key;
+7 -2
View File
@@ -1,6 +1,6 @@
/* CardElement.m - this file is part of SOPE
*
* Copyright (C) 2006-2014 Inverse inc.
* Copyright (C) 2006-2017 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -130,12 +130,17 @@
return values;
}
- (void) setValues: (NSMutableArray *) newValues
- (void) setValues: (id) newValues
atIndex: (NSUInteger) idx
forKey: (NSString *) key
{
NSMutableArray *oldValues, *subValues;
if (newValues && [newValues isKindOfClass: [NSString class]])
return [self setSingleValue: (NSString *)newValues
atIndex: idx
forKey: key];
oldValues = [self valuesForKey: key];
if (!oldValues)
{
+11 -1
View File
@@ -458,12 +458,22 @@
elements = [self childrenWithTag: aTag];
if (elements && [elements count] > 0)
{
// First element of type "pref"
prefElements = [elements cardElementsWithAttribute: @"type"
havingValue: @"pref"];
if (prefElements && [prefElements count] > 0)
element = [prefElements objectAtIndex: 0];
else
element = [elements objectAtIndex: 0];
{
// First element of type "work"
prefElements = [elements cardElementsWithAttribute: @"type"
havingValue: @"work"];
if (prefElements && [prefElements count] > 0)
element = [prefElements objectAtIndex: 0];
else
// Fallback
element = [elements objectAtIndex: 0];
}
}
else
element = nil;
+1 -3
View File
@@ -1,8 +1,6 @@
/* NGVCardPhoto.h - this file is part of NGCards
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2010-2016 Inverse inc.
*
* NGCards is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
+1 -3
View File
@@ -1,8 +1,6 @@
/* NGVCardPhoto.m - this file is part of NGCards
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2010-2016 Inverse inc.
*
* NGCards is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
+2 -2
View File
@@ -51,10 +51,10 @@
[aString appendString: @","];
subValue = [self objectAtIndex: count];
/* We MUST quote attribute values that have a ":" in them
/* We MUST quote attribute values that have a ":" or "," in them
and that not already quoted */
if (asAttributes && [subValue length] > 2
&& [subValue rangeOfString: @":"].length
&& ([subValue rangeOfString: @":"].length || [subValue rangeOfString: @","].length)
&& [subValue characterAtIndex: 0] != '"'
&& ![subValue hasSuffix: @"\""])
subValue = [NSString stringWithFormat: @"\"%@\"", subValue];
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Abidjan
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Accra
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Addis_Ababa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Algiers
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Asmara
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bamako
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bangui
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Banjul
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bissau
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Blantyre
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Brazzaville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bujumbura
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Cairo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Casablanca
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ceuta
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Conakry
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dakar
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dar_es_Salaam
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Djibouti
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Douala
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/El_Aaiun
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Freetown
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Gaborone
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Harare
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Johannesburg
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Juba
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kampala
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Khartoum
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kigali
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kinshasa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lagos
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Libreville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lome
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Luanda
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lubumbashi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lusaka
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Malabo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maputo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maseru
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mbabane
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mogadishu
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Monrovia
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nairobi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ndjamena
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Niamey
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nouakchott
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ouagadougou
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Porto-Novo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Sao_Tome
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tripoli
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tunis
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Windhoek
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Adak
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anchorage
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anguilla
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Antigua
+2 -2
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Araguaina
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Araguaina
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:BRT
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Buenos_Aires
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Buenos_Aires
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Catamarca
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Catamarca
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Cordoba
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Cordoba
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Jujuy
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Jujuy
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/La_Rioja
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/La_Rioja
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Mendoza
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Mendoza
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Rio_Gallegos
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Rio_Gallegos
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Salta
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Salta
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/San_Juan
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/San_Juan
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
Loaded 100 of 1020 files, more files were not shown because too many files have changed in this diff. Show more