mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-19 02:15:36 +00:00
Merge branch 'master' into feature-gdpr
This commit is contained in:
@@ -2,6 +2,87 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [5.9.1](https://github.com/Alinto/sogo/compare/SOGo-5.9.0...SOGo-5.9.1) (2023-12-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **addressbook:** Add global address book autocomplete on vlist ([11ad203](https://github.com/Alinto/sogo/commit/11ad203388ad33a22bd300047745869a27872cd9) [0b1f2b0](https://github.com/Alinto/sogo/commit/0b1f2b0405410628cb7ba8602b9286d71256d8e6) [0560efd](https://github.com/Alinto/sogo/commit/0560efd1f6a94bcb256d970ebe5535954e36cafe), [f85c531](https://github.com/Alinto/sogo/commit/f85c53190c38c4e28536f78e43623f6776248291))
|
||||
* **core:** Add mobile provisioning download for Apple's devices ([19915e3](https://github.com/Alinto/sogo/commit/19915e3dffc14c90b03277f9f97b4e6b1158aa87) [6d16ee7](https://github.com/Alinto/sogo/commit/6d16ee798863a7f196c14915c47888adf0758f1a) [d38cc86](https://github.com/Alinto/sogo/commit/d38cc86d29ffce580bf26dd278a6b68556471c14) [cd50ee0](https://github.com/Alinto/sogo/commit/cd50ee017656f3e6cfd46cff7147258d4893706b) [65f8336](https://github.com/Alinto/sogo/commit/65f8336255577566282039f4058fe4f3c38a16d4) [4fe01f9](https://github.com/Alinto/sogo/commit/4fe01f96d73690bf1a2d60755bb552d25324ccaf) [a273f7a](https://github.com/Alinto/sogo/commit/a273f7aca5df120a50af0486161880040ee20519))
|
||||
* **core:** add SOGoDisableExport option to disable export for mail, calendar and contacts ([d0b4b50](https://github.com/Alinto/sogo/commit/d0b4b50456cf3e23aa12d5cf7165531a7670edf6))
|
||||
* **core:** Add SOGoDisableSharingAnyAuthUser option to disable sharing to any user authenticated for mail, contacts and calendar ([e0ef59d](https://github.com/Alinto/sogo/commit/e0ef59d5f212aced72a17e3af9e72a434eedd68e))
|
||||
* **mail:** Add an option in Preferences to display full email instead of name alone in mailboxes ([2e670f7](https://github.com/Alinto/sogo/commit/2e670f7e6293b703f8cfe23ebf923ce13b463a19))
|
||||
* **mail:** Add SOGoMailHideInlineAttachments option to hide attachments when inline. Fixes [#5490](https://bugs.sogo.nu/view.php?id=5490). ([f41ab2e](https://github.com/Alinto/sogo/commit/f41ab2ed0c71903b80bda66adc54cc94b0cf70d6) [abce5f4](https://github.com/Alinto/sogo/commit/abce5f42cf4daef721ebf6b48d727eb957e20b14) [aa53524](https://github.com/Alinto/sogo/commit/aa535247513b06804fce666fe20ebcc9bd231c1f) [ca2c5c1](https://github.com/Alinto/sogo/commit/ca2c5c188ed980629f494e5b8e23ba42cdd54f58))
|
||||
* **password:** Add specials characters to POLICY_MIN_SPECIAL_SYMBOLS ([7d66699](https://github.com/Alinto/sogo/commit/7d666992198e5e91e29081b99443607b1c96d354))
|
||||
* **preferences:** can set SOGoForwardConstraints to 3 to accept both internal and external domains from SOGoForwardConstraintsDomains ([c872fb4](https://github.com/Alinto/sogo/commit/c872fb4d9c68382431a52181073ba1964cf44c22))
|
||||
* **reply:** add references header when replying ([b396a27](https://github.com/Alinto/sogo/commit/b396a277f00d879d2c179db780d6f621a9057d0c))
|
||||
* **ux:** select all button will unselect all if click again ([6e60b10](https://github.com/Alinto/sogo/commit/6e60b107556212123f41d95e4399d9605a4c16f9) [1ae02eb](https://github.com/Alinto/sogo/commit/1ae02ebd708da0a53ae588531e122adddaa7a5de))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **addressbook:** autocomplete correctly return two contacts from two ldap with same id ([1d3da92](https://github.com/Alinto/sogo/commit/1d3da92bab972ec7ec935eba72128e72387216c0))
|
||||
* **calendar:** do not let DURATION and DTEND be both present in vevent ([0023a9c](https://github.com/Alinto/sogo/commit/0023a9ce3c4027bb32699efc5529a4a53d7699f6))
|
||||
* **calendar:** If content is NSData, properly convert it to NSString ([21571ab](https://github.com/Alinto/sogo/commit/21571ab1e000da47b91b3f21bfaba89d1abec71f))
|
||||
* **calendar:** properly set the start date range for yearly events ([1e8127b](https://github.com/Alinto/sogo/commit/1e8127b46122e83df02c394536950288b0ee16aa))
|
||||
* **core:** Add cache for CDefaultsSize to avoid spamming SQL request ([87e1240](https://github.com/Alinto/sogo/commit/87e1240ace297645559e698a8c1f1a76b9901895) [81f2d88](https://github.com/Alinto/sogo/commit/81f2d88db362cc21c50858295d0e9d375db61f67))
|
||||
* **core:** Fix calendar issues with Thunderbird related to vlist exclusion. Fix error log on photo. Closes [#5885](https://bugs.sogo.nu/view.php?id=5885) ([6b08f2e](https://github.com/Alinto/sogo/commit/6b08f2e4decc87ee57609355dee5a6657bca6110))
|
||||
* **core:** Fix user profile retrieval when using utf8mb4_bin collation - in this case the SQL results may return NSdata instead of NSString. Fixes [#5902](https://bugs.sogo.nu/view.php?id=5902). ([3cd9910](https://github.com/Alinto/sogo/commit/3cd991063805f88a5672b10fbcc04a4149e13e26))
|
||||
* **hmtl:** prevent html injection of tag form ([7481ccf](https://github.com/Alinto/sogo/commit/7481ccf37087c3f456d7e5a844da01d0f8883098))
|
||||
* **http:** set correct Accept header when dowloading eml file ([c569ed2](https://github.com/Alinto/sogo/commit/c569ed2d77cf23c274c3dfc7cd3533cf268d09af))
|
||||
* **mail:** Clean temporary files when mail is sent ([f35a37b](https://github.com/Alinto/sogo/commit/f35a37bbdd2005a63b42f9bab1588ce9a935b112) [d163405](https://github.com/Alinto/sogo/commit/d1634054d6f4dd18bdb82a7903b3bbbceae5b0e8))
|
||||
* **mail:** Fix duplication of images when saving draft. Fixes [#5888](https://bugs.sogo.nu/view.php?id=5888) ([ee9899f](https://github.com/Alinto/sogo/commit/ee9899fe3d6aa7bf694f959a8e4f09faa39e737a) [9c09485](https://github.com/Alinto/sogo/commit/9c0948518b1e8365d6fadb3fccae1a0257b518ed))
|
||||
* **scripts:** wrong type for c_value in script for complete unicode coverage ([65374e4](https://github.com/Alinto/sogo/commit/65374e44fc2a861d3a7c9f1f9ba25505601d79f1))
|
||||
* **sogo-tool:** add protection to expire-sessions if the input is not an integer ([bb943e4](https://github.com/Alinto/sogo/commit/bb943e414d3fc8b71ebb169e31c261cd2dcd6d37))
|
||||
* **translation:** incorret value causing trouble to transifex ([4b45dc7](https://github.com/Alinto/sogo/commit/4b45dc7584984602071efe99b9638c6231efba8c))
|
||||
|
||||
|
||||
### Localization
|
||||
|
||||
* **ar:** Update Arabic translations ([28d883d](https://github.com/Alinto/sogo/commit/28d883dac1ccbafb878b9e13ba38f570f44ea325))
|
||||
* **bg_BG:** Update Bulgarian translations ([3815bc1](https://github.com/Alinto/sogo/commit/3815bc1c5e6fe37aaad5492c246697fe34e4286d))
|
||||
* **bs_BA:** Update Bosnian translations ([2afbcbe](https://github.com/Alinto/sogo/commit/2afbcbeaed24571785437aa5af1c092ba129ce97))
|
||||
* **ca:** Update Catalan translations ([3040543](https://github.com/Alinto/sogo/commit/3040543c797fe9176df048b8a72a2c6f7dbfd3b7))
|
||||
* **cs:** Update Czech translations ([029a821](https://github.com/Alinto/sogo/commit/029a82143f1d0d82ca8d6a5c9e5a14ac351718bf))
|
||||
* **cy:** Update Welsh translations ([06a6ed7](https://github.com/Alinto/sogo/commit/06a6ed776824f47e5606c29a162903380e72fbd9))
|
||||
* **da_DK:** Update Danish translations ([76911fd](https://github.com/Alinto/sogo/commit/76911fd4454c9f0213f11b4e2e95b29010eed9a4))
|
||||
* **de:** Update German translations ([8a4bc2a](https://github.com/Alinto/sogo/commit/8a4bc2a71642a2a431008c02214ffdd0eb2ace23))
|
||||
* **es_AR:** Update SpanishArgentina translations ([527fded](https://github.com/Alinto/sogo/commit/527fded19ceaf995963e997659b79c5e1290b8c5))
|
||||
* **es_ES:** Update SpanishSpain translations ([057a1ba](https://github.com/Alinto/sogo/commit/057a1ba1053f462cd0633b86c3ee86d76acbd6bb))
|
||||
* **eu:** Update Basque translations ([33f3a1b](https://github.com/Alinto/sogo/commit/33f3a1b716a006df8a28c416fc947e44fc285e37))
|
||||
* **fi:** Update Finnish translations ([dba2332](https://github.com/Alinto/sogo/commit/dba2332864fa38116615c9b58eb3590fe251a37a))
|
||||
* **gl:** Change Galician name to Galego ([6eae3f2](https://github.com/Alinto/sogo/commit/6eae3f2b1601033558a791c27bc4e27acf0825e7))
|
||||
* **gl:** Update Galician translations ([5aa7ebf](https://github.com/Alinto/sogo/commit/5aa7ebf2aefef6e45423b2193c136fadced51375))
|
||||
* **he:** Update Hebrew translations ([694c21d](https://github.com/Alinto/sogo/commit/694c21de99522733c95304d0e775e81493ff7200))
|
||||
* **hr_HR:** Update Croatian translations ([715d25d](https://github.com/Alinto/sogo/commit/715d25d40a84b518b1d8f97b4946045a4be761b5))
|
||||
* **hu:** Update Hungarian translations ([0b22fa6](https://github.com/Alinto/sogo/commit/0b22fa6cd5b55db5d021bbbfcc53d411ff4bb9d7))
|
||||
* **id_ID:** Update Indonesian translations ([a16d29b](https://github.com/Alinto/sogo/commit/a16d29b70b50eeee14a3ad1b627e8f8a59216461))
|
||||
* **is:** Update Icelandic translations ([2de6241](https://github.com/Alinto/sogo/commit/2de624122045d9df877f39f665d271056af0fba8))
|
||||
* **it:** Update Italian translations ([53036b3](https://github.com/Alinto/sogo/commit/53036b323fe65b4bf40c838ff0578fa076bfea93))
|
||||
* **ja:** Update Japanese translations ([41fb85e](https://github.com/Alinto/sogo/commit/41fb85e6a320b25776ce63672ef4251e932f82f0))
|
||||
* **kk:** Update Kazakh translations ([2174195](https://github.com/Alinto/sogo/commit/21741954dd2762b3f03c0b5b21b8feb4d826cfb1))
|
||||
* **lt:** Update Lithuanian translations ([6e9e7f9](https://github.com/Alinto/sogo/commit/6e9e7f98ef379ce26937e00daedfad88383615a4))
|
||||
* **lv:** Update Latvian translations ([a9ecaed](https://github.com/Alinto/sogo/commit/a9ecaed5fa6fe8fecf08ec0354bbb187824d2fbb))
|
||||
* **mk_MK:** Update Macedonian translations ([d6c9ecd](https://github.com/Alinto/sogo/commit/d6c9ecdeb0490fa44bc1c444819b5c82ccf89073))
|
||||
* **nb_NO:** Update NorwegianBokmal translations ([3d5f352](https://github.com/Alinto/sogo/commit/3d5f35211189802ef031be688cadddc2ab684d37))
|
||||
* **nl:** Update Dutch translations ([402c3d0](https://github.com/Alinto/sogo/commit/402c3d0a1f83d32af2fca2f3e5abafbe8850de08))
|
||||
* **nn_NO:** Update NorwegianNynorsk translations ([6d270fe](https://github.com/Alinto/sogo/commit/6d270fe7a4bad2253f7e8427be660405460b2139))
|
||||
* **pl:** Update Polish translations ([c75f210](https://github.com/Alinto/sogo/commit/c75f210864de1a7bb313c1ba21be987143a2f7ca))
|
||||
* **pt_BR:** Update BrazilianPortuguese translations ([cfab856](https://github.com/Alinto/sogo/commit/cfab85624b3e725f121ea61d181340189e969229))
|
||||
* **pt:** Update Portuguese translations ([e4f07c4](https://github.com/Alinto/sogo/commit/e4f07c466e195d59f72b934567cb3aa4d18cb9f3))
|
||||
* **ro_RO:** Update Romanian translations ([d9c716c](https://github.com/Alinto/sogo/commit/d9c716c1b679a792876c9bc7ebed2d530ab8d89f))
|
||||
* **ru:** Update Russian translations ([3809ec3](https://github.com/Alinto/sogo/commit/3809ec3904a7882239e50c671aa72c9f7f013c62))
|
||||
* **sk:** Update Slovak translations ([cd7e06c](https://github.com/Alinto/sogo/commit/cd7e06c2ede339d078e54b76b6078523b78383fc))
|
||||
* **sl_SI:** Update Slovenian translations ([ca21bf4](https://github.com/Alinto/sogo/commit/ca21bf4ce1758717eac8ec961788d067e9428456))
|
||||
* **sr_ME@latin:** Update Montenegrin translations ([fe7369e](https://github.com/Alinto/sogo/commit/fe7369e427d7cc6f4efb23a78437bd2b2c65e6cd))
|
||||
* **sr@latin:** Update SerbianLatin translations ([9126cae](https://github.com/Alinto/sogo/commit/9126cae27d49b7f199f2a6b259eb40589b011a55))
|
||||
* **sr:** Update Serbian translations ([ed444fd](https://github.com/Alinto/sogo/commit/ed444fdc2266888f9d15d557e1ba92896158d870))
|
||||
* **sv:** Update Swedish translations ([10369aa](https://github.com/Alinto/sogo/commit/10369aa654058b50285ae7239a9356f736c7ac1c))
|
||||
* **tr_TR:** Update TurkishTurkey translations ([8d1fc1e](https://github.com/Alinto/sogo/commit/8d1fc1e306d926b3efeab2e3017823201254caf0))
|
||||
* **uk:** Update Ukrainian translations ([0e50d37](https://github.com/Alinto/sogo/commit/0e50d37531d850b46009af2af5049a6b46541da0))
|
||||
* **zh_CN:** Update ChineseChina translations ([cf87022](https://github.com/Alinto/sogo/commit/cf87022348296b9659e83e3a3985b48d89f5e01f))
|
||||
* **zh_TW:** Update ChineseTaiwan translations ([fc2a82c](https://github.com/Alinto/sogo/commit/fc2a82c3b0f4b780df3b4d27ad0da78e34f665c6))
|
||||
|
||||
## [5.9.0](https://github.com/Alinto/sogo/compare/SOGo-5.8.3...SOGo-5.9.0) (2023-09-27)
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ devices with SOGo.
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available
|
||||
at https://sogo.nu/downloads/documentation.html.
|
||||
at https://www.sogo.nu/support.html#/documentation.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -693,6 +693,13 @@ Defaults to `NO` when unset.
|
||||
|S |SOGoDisableSharing
|
||||
|List of modules where sharing should be disabled, for example `(Mail, Calendar)`. Modules can be `Mail`, `Contacts` and `Calendar`. Default value empty list (sharing enabled for everybody).
|
||||
|
||||
|S |SOGoDisableSharingAnyAuthUser
|
||||
|List of modules where sharing with any authenticated user option should be disabled, for example `(Mail, Calendar)`. Modules can be `Mail`, `Contacts` and `Calendar`. Default value empty list (sharing enabled for everybody).
|
||||
|
||||
|S |SOGoDisableExport
|
||||
|List of modules where export should be disabled, for example `(Mail, Calendar)`. Modules can be `Mail`, `Contacts` and `Calendar`. Default value empty list (export enabled for everybody).
|
||||
|
||||
|
||||
|S |SOGoPasswordChangeEnabled
|
||||
|Parameter used to allow or not users to change their passwords from
|
||||
SOGo.
|
||||
@@ -819,8 +826,17 @@ specified as an array of dictionaries.
|
||||
|D |SOGoCreateIdentitiesDisabled
|
||||
|Disable identity creation for users in preferences. If `YES`, users won't be able to add new identities and will allow to change only full name, signature and default identity. Default value is `NO`. Note : If this settings is set to `YES`, it will not be possible to crete auxiliary mail accounts.
|
||||
|
||||
<<<<<<< HEAD
|
||||
|S |SOGoURLEncryptionEnabled
|
||||
|Enable URL encryption to make SOGo GDPR compatible. Setting this parameter to `YES` will encrypt username in URL. The encryption data are cached to avoid high cpu usage. If the encryption is enabled, the DAV url will change. Default value is `NO`.
|
||||
||||||| 65f833625
|
||||
=======
|
||||
|S |SOGoGlobalAddressBookFirstEntries
|
||||
|Display first entries in Global Address Book. Default value is `NO`. If source is LDAP, the LDAP overlay `sssvlv` must be enabled on the system for server side sorting.
|
||||
|
||||
|S |SOGoGlobalAddressBookFirstEntriesCount
|
||||
|Number of entries displayed when `SOGoGlobalAddressBookFirstEntries` is enabled. Default value is `100`.
|
||||
>>>>>>> master
|
||||
|
||||
|S |SOGoURLEncryptionPassphrase
|
||||
|Passphrase for `SOGoURLEncryptionEnabled`. The string must be 128 bits (16 characters). If this settings change, the cache server must be restarted, and the DAV url will change. Default value is `SOGoSuperSecret0`.
|
||||
@@ -2277,12 +2293,14 @@ Defaults to `NO` when unset.
|
||||
|D |SOGoForwardConstraints
|
||||
|Parameter used to set constraints on possible addresses used when
|
||||
automatically forwarding mails. When set to `0` (default), no constraint
|
||||
is enforced. When set to `1`, only internal domains can be used. When
|
||||
set to `2`, only external domains can be used.
|
||||
is enforced. When set to `1`, only internal domains can be used.
|
||||
When set to `2`, only external domains defined in `SOGoForwardConstraintsDomains`
|
||||
can be used. When set to `3`, internal domains and other domains defined
|
||||
in `SOGoForwardConstraintsDomains` can be used.
|
||||
|
||||
|D |SOGoForwardConstraintsDomains
|
||||
|Parameter used to set which domains are allowed as external domains
|
||||
when SOGoForwardConstraints is set to `2`. For example, setting:
|
||||
|Parameter used to set which external domains are allowed
|
||||
when SOGoForwardConstraints is set to `2` or `3`. For example, setting:
|
||||
|
||||
SOGoForwardConstraintsDomains = ("gmail.com", "googlemail.com");
|
||||
|
||||
@@ -2485,6 +2503,13 @@ Defaults to `NO` when unset.
|
||||
|
||||
Defaults to `inline` when unset.
|
||||
|
||||
|U |SOGoMailDisplayFullEmail
|
||||
|Show recipients or sender full email in mailboxes if set to `YES`. Default value is `NO`.
|
||||
|
||||
|U |SOGoMailHideInlineAttachments
|
||||
|Hide inline message as attachements if set to `YES`. Default value is `NO`.
|
||||
|
||||
|
||||
|U |SOGoMailCustomFullName
|
||||
|The string to use as full name when composing an email, if
|
||||
_SOGoMailCustomFromEnabled_ is set in the user's domain defaults.
|
||||
@@ -3210,7 +3235,7 @@ your site. However, be aware that in order to use the SOGo Integrator
|
||||
plug in, you will need to repackage it with specific modifications.
|
||||
Please refer to the documentation published online:
|
||||
|
||||
https://sogo.nu/downloads/documentation.html
|
||||
https://www.sogo.nu/support.html#/documentation
|
||||
|
||||
If you only use the SOGo Connector plug in, you can still easily access
|
||||
your data.
|
||||
@@ -3247,6 +3272,12 @@ http://127.0.0.1/SOGo/dav/jdoe/
|
||||
|
||||
Note that the trailing slash is important for the old Apple iCal 3 application.
|
||||
|
||||
Since SOGo 5.9.1, calendar can be installed using provisioning profiles. On the calendar interface next to the calendar name (eg `Personal`), click on the three dots button and click on `Download iOS - MacOS configuration profile`.
|
||||
You have to add the profile to your device :
|
||||
|
||||
* Go to Settings / Profiles / Click on + / Continue
|
||||
* Type your SOGo account password and click on install
|
||||
|
||||
Apple AddressBook
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -3290,6 +3321,12 @@ The virtual host should be defined like:
|
||||
This configuration is also required if you want to configure a CardDAV
|
||||
account on an Apple iOS device (version 4.0 and later).
|
||||
|
||||
Since SOGo 5.9.1, address book can be installed using provisioning profiles. On the address book interface next to the address book name (eg `Personal`), click on the three dots button and click on `Download iOS - MacOS configuration profile`.
|
||||
You have to add the profile to your device :
|
||||
|
||||
* Go to Settings / Profiles / Click on + / Continue
|
||||
* Type your SOGo account password and click on install
|
||||
|
||||
Microsoft ActiveSync
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -3300,6 +3337,488 @@ any mobile devices that support Microsoft ActiveSync. Microsoft Outlook
|
||||
The Microsoft ActiveSync server URL is generally something
|
||||
like: `http://127.0.0.1/Microsoft-Server-ActiveSync`.
|
||||
|
||||
Using sogo-tool
|
||||
---------------
|
||||
The command _sogo-tool_ allows to do some operations on database and sieve filter. It is included with
|
||||
the sogo package on Debian/Ubuntu but must be installed manually on RHEl/CentOS:
|
||||
|
||||
yum install sogo-tool
|
||||
|
||||
*_WARNING_: Use sogo-tool with full awareness of what you are doing. This is an admin tool that can cause loss of data
|
||||
or completely make the webmail unusable by a user.*
|
||||
|
||||
sogo-tool backup/restore
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The backup tool saves the information of a user into a file. The information saved are its preferences, its events and its contacts.
|
||||
|
||||
sogo-tool backup directory ALL|user1 [user2] ...
|
||||
|
||||
* First argument, *directory* must be a path, only the last subdirectory will be created, the previous ones must exist.
|
||||
* Second argument is *ALL* to backup all users or put each user space-separated.
|
||||
* Each user's info will take one file, the filename will be the username.
|
||||
* The files are readable but in a specific format for _sogo-tool restore_.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool backup /tmp/foo ALL # Will save all users into /tmp/foo
|
||||
sogo-tool backup /etc/sogo_backup/foo user1 user2 # Will save only user1 and user2. The directory /etc/sogo_backup must exist.
|
||||
----
|
||||
|
||||
Using the files produced by the backup, you can restore all or some information of a user with the _restore_ command:
|
||||
|
||||
sogo-tool restore [-l|-p|-f/-F folder/ALL] [-c credentialFile] directory user
|
||||
|
||||
* First argument must be one of the four mode options *-l*, *-p*, *-f* or *-F*.
|
||||
* Second, optional, is *-c* with the credential file. Only useful with *-p* mode.
|
||||
* *directory* is the path where the backup file is.
|
||||
* *user* is the name of the backup file, which is the username if you use the _backup_ tool.
|
||||
|
||||
The differents mode are:
|
||||
|
||||
* *-l* will only list the folders (meaning calendar and address book) that would be restored with *-f* or *-F*.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool restore -l /tmp/backup user1
|
||||
----
|
||||
Result:
|
||||
----
|
||||
Calendar/60C8-65323D80-7-4D9F7D80 (new_calendar)
|
||||
Calendar/personal (Personal Calendar)
|
||||
Contacts/personal (Personal Address Book)
|
||||
----
|
||||
|
||||
* *-p* will restore the user's preferences. If the user has an active sieve script (filter, vacation, forward...) you must provide a credential file with
|
||||
the parameters *-c*. The credential file is a simple one-line file that contains the "username:password" of an admin account of your imap/sieve server.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool restore -p /tmp/backup user1
|
||||
sogo-tool restore -p -c /var/sogo/cred /tmp/backup user1
|
||||
----
|
||||
|
||||
* *-f* will restore the events/contacts of folders (calendar and address book) from the backup file that don't exist in the database. If the event/contact
|
||||
was deleted but is in the backup file, it will be restored. If the event/contact exist, nothing will be done even if it has been modified compared to the
|
||||
backup file. If a whole folder has been deleted but is in the backup file, it will be restored. *-f* expect a value that can be ALL to restore all folders,
|
||||
or the name of the folder to restore. You can list them with the *-l* mode.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool restore -f ALL /tmp/backup user1
|
||||
sogo-tool restore -f "Contacts/personal" tmp/backup user1
|
||||
sogo-tool restore -f "Calendar/60C8-65323D80-7-4D9F7D80" tmp/backup user1
|
||||
----
|
||||
The commands will either prints out nothing or any events/contacts restored:
|
||||
----
|
||||
restoring record '60CA-65323D00-1-680B0A00.ics'
|
||||
restoring record '60C8-65323D00-1-4D9F7D80.vcf'
|
||||
restoring record '60C8-65323D80-9-4D9F7D80.ics'
|
||||
----
|
||||
|
||||
* *-F* has the same behavior as *-f* but it will first delete all contacts and events in database before restoring the backup.
|
||||
So if an event/contact is not in the backup file, it will be lost. If a folder exists but is not in the backup file, nothing will happen
|
||||
to it and its content.
|
||||
|
||||
*-F* expect a value that can be ALL to restore all folders, or the name of the folder to restore. You can list them with the *-l* mode.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool restore -F ALL /tmp/backup user1
|
||||
sogo-tool restore -F "Contacts/personal" tmp/backup user1
|
||||
sogo-tool restore -F "Calendar/60C8-65323D80-7-4D9F7D80" tmp/backup user1
|
||||
----
|
||||
|
||||
sogo-tool checkup
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Check the events and contacts data's integrity of a user
|
||||
|
||||
sogo-tool checkup [-d] user...
|
||||
|
||||
* *-d*, optional, will delete all corrupted data.
|
||||
* *user* is a single username or multiple user each space-separated.
|
||||
|
||||
Will print out nothing if no corrupted data were found or one of the following messages:
|
||||
|
||||
* Corrupted calendar item (missing tags) in path <path> with c_name = <ics_id>
|
||||
* Corrupted calendar item (unparsable) in path <path> with c_name = <ics_id>
|
||||
* Missing start date of event in path <path> with c_name = <ics_id> (<event_name>)"
|
||||
* Missing end date of event in path <path> with c_name = <ics_id> (<event_name>)"
|
||||
* Start date (<start_date>) is not before end date (<end_date>) for event in path <path> with c_name = <ics_id> (<event_name>)
|
||||
* Corrupted card item (unparsable) in path <path> with c_name = <vcard_id>
|
||||
|
||||
It can also print log from SOGo if it raise errors:
|
||||
|
||||
* <0x0x55e0956c4d00[VSCardSaxDriver]> serious inconsistency among begin/end tags
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool checkup user1
|
||||
sogo-tool checkup -d user1
|
||||
----
|
||||
|
||||
sogo-tool cleanup
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Will purge all user's deleted events and contacts which the deletion is older than a number of days.
|
||||
|
||||
sogo-tool cleanup [days] ALL|user1 [user2]
|
||||
|
||||
* *days* the age of deleted records to purge in days
|
||||
* Second argument is *ALL* to purge events of all users or put each user space-separated.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool cleanup 30 ALL
|
||||
sogo-tool cleanup 30 user1 user2
|
||||
----
|
||||
Outputs:
|
||||
----
|
||||
Purged 3 records from folder /Users/user1/Calendar/60C7-65325300-9-18F39AA0
|
||||
Purged 1 records from folder /Users/user1/Calendar/60C8-65323D80-7-4D9F7D80
|
||||
Purged 0 records from folder /Users/user1/Calendar/personal
|
||||
Purged 0 records from folder /Users/user1/Contacts/personal
|
||||
Purged 5 records from folder /Users/user2/Calendar/personal
|
||||
----
|
||||
|
||||
|
||||
sogo-tool create-folder
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a folder (Calendar or Address Book) for a user.
|
||||
|
||||
create-folder user type [displayname ...]
|
||||
|
||||
* *user* is the name of the user
|
||||
* *type* is either "Calendar" or "Contacts"
|
||||
* *displayname* is the folder's name. If the name is already taken, a new folder will still be made but with another uid.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool create-folder user1 Contacts Pro_Contacts Ext_Contacts
|
||||
sogo-tool create-folder user2 Calendar Pro_Calendar
|
||||
----
|
||||
|
||||
|
||||
sogo-tool dump-defaults
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Output all current defaults value of GNUstep and SOGo (sogo.conf)
|
||||
|
||||
sogo-tool dump-defaults [-f <filename>|[all]]
|
||||
|
||||
* Can be used without arguments and will output the defaults for gnustep domain 'sogod'.
|
||||
* *all* option will output all defaults value found from sogo and gnustep in property list format.
|
||||
* *-f* expect a filepath of an .xml file and will output it in property list format (sogo.conf). May need some tweaks, though.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool dump-defaults
|
||||
sogo-tool dump-defaults all
|
||||
sogo-tool dump-defaults -f /tmp/foo/conf.xml
|
||||
----
|
||||
|
||||
sogo-tool expire-sessions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Expires user sessions from database without activity for specified number of minutes. When a user log in to sogo for
|
||||
the first time, sogo will create a entry in database's table OCSSessionsFolderURL with the user's information. Sogo will
|
||||
also set a cookie with an encoded value to fetch this database table. That way, each time the user make a request with that cookie,
|
||||
sogo will know which connected user it is. This command will remove all user's session from database
|
||||
without activity for specified number of minutes. Those users will have to log in again.
|
||||
|
||||
sogo-tool expire-sessions [nbMinutes]
|
||||
|
||||
* *nbMinutes* Integer, number of minutes. All session without activity in these last minutes will be removed.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool expire-sessions #Will print usage.
|
||||
sogo-tool expire-sessions 160 #Will remove session which last activity is older than 160 minutes.
|
||||
sogo-tool expire-sessions 0 #Will remove session which last activity is older than 0 minutes.
|
||||
----
|
||||
|
||||
sogo-tool manage-acl
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Manage access-control list (ACL) of a user for folders (Calendar and Address Book).
|
||||
|
||||
sogo-tool manage-acl get|add|remove|subscribe|unsubscribe owner folder user|group <rights>
|
||||
|
||||
* First argument is the action among *get*, *add*, *remove*, *subscribe* and *unsubscribe*.
|
||||
* Second argument is the username of the folder's owner.
|
||||
* Third argument is the name of the folder.
|
||||
* Fourth argument is the user whom to manage its acl. It also can be _ALL_, _anonymous_ and _<defaults>_.
|
||||
* Fifth argument, only needed with *add* action, is the rights to set for the user.
|
||||
|
||||
The actions:
|
||||
|
||||
* *get* will print out the folder's rights of the user or nothing if the user is not found or doesn't have any rights.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool manage-acl get sogo-tests1 Calendar/5E1F-653FC400-1-38155940 sogo-tests2
|
||||
----
|
||||
Result:
|
||||
----
|
||||
Rights for sogo-tests2 ["PublicModifier", "ConfidentialModifier", "PrivateModifier", "ObjectCreator", "ObjectEraser"]
|
||||
----
|
||||
|
||||
* *add* will add the given rights to the user for the given folder. the value right is a json string of an array with each right to set.
|
||||
Be Careful as there is no check for the rights already set. It could be better to first remove them, then add them.
|
||||
|
||||
The rights for Address Book are:
|
||||
|
||||
* _ObjectCreator_: can create cards (contact of list)
|
||||
* _ObjectEditor_: can modify cards
|
||||
* _ObjectViewer_: can view cards
|
||||
* _ObjectEraser_: can delete cards
|
||||
|
||||
The rights for Calendar are:
|
||||
|
||||
* _ObjectCreator_: can create event or task
|
||||
* _ObjectEraser_: can delete event or task
|
||||
* _<type>_ can be _Public_, _Confidential_ or _Private_
|
||||
* _<type>Viewer_: can view the whole events (ex: PrivateViewer)
|
||||
* _<type>DAndTViewer_: can only view the date and time of events
|
||||
* _<type>Modifier_: can view and edit the events
|
||||
* _<type>Responder_: can view the events
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool manage-acl add sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2 '["ObjectViewer", "ObjectEraser"]'
|
||||
----
|
||||
|
||||
* *remove* all user's rights to the folder.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool manage-acl remove sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2
|
||||
----
|
||||
|
||||
* *subscribe* the user to the folder.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool manage-acl subscribe sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2
|
||||
----
|
||||
|
||||
* *unsubscribe* the user to the folder.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool manage-acl unsubscribe sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2
|
||||
----
|
||||
|
||||
sogo-tool manage-eas
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Manage EAS folders
|
||||
|
||||
sogo-tool manage-eas listdevices|listfolders|resetdevice|resetfolder|mergevcard|mergevevent user <deviceId | folderId> <YES | NO>
|
||||
|
||||
* First argument is the action among *listdevices*, *listfolders*, *resetdevice*, *resetfolder*, *mergevcard* and *mergevevent*.
|
||||
* Second argument is the *user* whom to perform the action.
|
||||
* Third argument is the *deviceId* of, if the action is *resetFolder*, the *folderId*. No need of this argument if the action is *listdevices*
|
||||
* Fourth argument, only use with *mergevcard* and *mergevevent* is either YES to merge and *NO* to un-merge.
|
||||
|
||||
The actions:
|
||||
|
||||
* *listdevices*: list the devices belonging to user.
|
||||
* *listfolders*: list all folders of deviceId for user.
|
||||
* *resetdevice*: force deviceId of user to resync everything.
|
||||
* *resetfolder*: force folderId of user to resync everything.
|
||||
* *mergevcard*: merge/un-merge all addressbooks into one for deviceId of user.
|
||||
* *mergevevent*: merge/un-merge all calendars into one for deviceId of user.
|
||||
|
||||
Examples:
|
||||
----
|
||||
sogo-tool manage-eas listdevices janedoe
|
||||
sogo-tool manage-eas listfolders janedoe androidc316986417
|
||||
sogo-tool manage-eas resetdevice janedoe androidc316986417
|
||||
sogo-tool manage-eas resetfolder janedow androidc316986417 folderlala-dada-sasa_7a13_1a2386e0_e
|
||||
sogo-tool manage-eas mergevcard janedow androidc316986417 YES
|
||||
sogo-tool manage-eas mergevevent janedow androidc316986417 YES
|
||||
----
|
||||
|
||||
sogo-tool remove
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Remove all folders (Calendar and Address Book) and Preference settings of a user. The personal Calendar and Address Book
|
||||
will stay but be emptied of all entries. The Preferences will go back to defaults values as for a new user.
|
||||
|
||||
sogo-tool remove user1 [user2]
|
||||
|
||||
* Arguments one user or several space-separated.
|
||||
* You can add -v after sogo*tool to list all removed folders
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool remove user1
|
||||
sogo-tool -v remove user2
|
||||
----
|
||||
Output example with -v options:
|
||||
----
|
||||
Deleting /Users/user2/Calendar/B088-65363400-3-2B9DF0C0
|
||||
Deleting /Users/user2/Calendar/personal
|
||||
Deleting /Users/user2/Contacts/B087-65363380-5-374DA380
|
||||
Deleting /Users/user2/Contacts/B087-65363400-7-374DA380
|
||||
Deleting /Users/user2/Contacts/personal
|
||||
----
|
||||
|
||||
sogo-tool remove-doubles
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
remove duplicate contacts from the specified user addressbook
|
||||
|
||||
sogo-tool remove-doubles USER FOLDER
|
||||
|
||||
* *USER* is the name of the user to perform the removal
|
||||
* *FOLDER* is the name of the folder to clean from duplicates
|
||||
|
||||
Two contacts are considered duplicates when they have the same mails or display name. When two or more contacts
|
||||
are duplicates, each one will get a score. The ones with the highest score will be kept and the others
|
||||
will be discarded. If two records have the same score, the first one to have reach it will be kept.
|
||||
The scores are distributed as such:
|
||||
* Record which has been the last modified: +1
|
||||
* Record has the most content: +2
|
||||
* Record has the most quick field set: +3
|
||||
* Record is in a contact list: +6
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool remove-doubles user1 personal
|
||||
sogo-tool remove-doubles user2 489-65376E80-1-2D2BA000
|
||||
----
|
||||
|
||||
sogo-tool rename-user
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Update records pertaining to a user after a change of user id. Will change all folders path, subscriptions from others users,
|
||||
all mention of user id in database.
|
||||
|
||||
sogo-tool rename-user fromuserid touserid
|
||||
|
||||
* *fromuserid* Previous user id
|
||||
* *touserid* New user id
|
||||
|
||||
If the new user id already exist, the command will output a message and do nothing.
|
||||
**WARNING** This command only change database of sogo, if you use ldap or others databases they will still keep the old id.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool rename-user old_username new_username
|
||||
----
|
||||
|
||||
sogo-tool truncate-calendar
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Remove old calendar entries from the specified user calendar.
|
||||
|
||||
sogo-tool truncate-calendar [-r] USER FOLDER DATE
|
||||
|
||||
* *-r* optional, to also delete recurrent events that have occurrence after *DATE*
|
||||
* *USER* is the name of the owner of the calendar
|
||||
* *FOLDER* is the name of the calendar folder to clean up
|
||||
* *DATE* UTC datetime, event older than this date will be removed
|
||||
|
||||
Without *-r*, only reccurrent events which all occurrences are older than *DATE* will be removed.
|
||||
With *-r*, event the if there are occurrences after *DATE*, the recurrent event will be removed.
|
||||
*DATE* can take the value `date +%FT%T` which is the current time
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool truncate-calendar sogo-tests1 personal 2023-10-25T00:00:00
|
||||
sogo-tool truncate-calendar -r sogo-tests2 5E38-6538BE80-5-AFF8310 2022-01-01T15:30:00
|
||||
sogo-tool truncate-calendar -r sogo-tests2 personal `date +%FT%T` #will delete all event older than now
|
||||
----
|
||||
Result:
|
||||
----
|
||||
No record to remove. All records kept.
|
||||
----
|
||||
----
|
||||
Removing 1 records...
|
||||
Removed 1 records.
|
||||
----
|
||||
|
||||
sogo-tool update-autoreply
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
_This command is only useful if your sieve server doesn't have the capabilities *date* or *relational*_
|
||||
In that case this command will check vacation's setting of all the users. If vacation is enabled/disabled,
|
||||
the starting and ending date, the body and others parameters. If needed, the command
|
||||
will write the sieve script accordingly.
|
||||
|
||||
sogo-tool update-autoreply -p credentialFile
|
||||
|
||||
* *-p- The credential file, a simple one-line file that contains "username:password" of an admin account of your imap/sieve server.
|
||||
|
||||
Example:
|
||||
----
|
||||
sogo-tool update-autoreply -p /var/sogo/cred
|
||||
----
|
||||
|
||||
sogo-tool user-preferences
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Get, set or unset user defaults / settings in the database.
|
||||
|
||||
_Settings_ stores parameters for user's calendar, mail and contacts. It can be graphic
|
||||
as month view or week view for calendar but it also stores subscription, delegation...
|
||||
It also stores the private Salt for TOTP and the parameter ForceResetPassword to force the
|
||||
user to change password.
|
||||
|
||||
_Defaults_ stores all parameters that can be found in Preferences panel. So it goes from default language to
|
||||
autoreply to many others options.
|
||||
|
||||
|
||||
user-preferences get|set|unset defaults|settings user key [value|-f filename] [-p credentialFile]
|
||||
|
||||
* First argument is the action *get*, *set* or *unset*
|
||||
* Second argument is parameter type *settings* or *defaults*
|
||||
* Third argument *user* is the name of the user where to make the action
|
||||
* Fourth argument *key* is the name of the parameters where to make the action
|
||||
* If the action is *set*, you should provide either *value* as fifth argument or a file with the value inside with *-f* filename/path
|
||||
* If the action is *set* or *unset* and the *key* concerns a sieve script (filter, vacation, forward...), you
|
||||
should provide a credential file, a one-line file that contains "username:password" of an admin account of your imap/sieve server.
|
||||
|
||||
As there is a lot of parameters, this documentation will not go into details for each one. To know what are
|
||||
the key names and their value you should got to your database in table defined by _SOGoProfileURL_ in your sogo.conf.
|
||||
Here, for each row (user) you will find c_defaults and c_settings which are json with the keys. However, if
|
||||
a parameter has never been set, it won't appears in those json. The clean way to know the missing keys is to
|
||||
set it up in one of your dummy/dev/test account then see the values in _SOGoProfileURL_. Be careful, a value
|
||||
can be a json itself, only the primary key can be get/set/unset.
|
||||
|
||||
Example with forwarding, *get* action:
|
||||
----
|
||||
sogo-tool user-preferences get defaults user1 Forward
|
||||
----
|
||||
If forward has never been set the result will be:
|
||||
----
|
||||
Value for key "Forward" not found in defaults
|
||||
----
|
||||
Else it will be
|
||||
----
|
||||
{"forwardAddress":["sogo-tests2@sogo.alinto"],"enabled":1,"keepCopy":1}
|
||||
----
|
||||
|
||||
*unset* action:
|
||||
----
|
||||
sogo-tool user-preferences unset defaults user1 Forward -p /etc/sogo/cred
|
||||
----
|
||||
|
||||
*set* action:
|
||||
----
|
||||
sogo-tool user-preferences set defaults user1 Forward '{"forwardAddress":["sogo-tests2@sogo.alinto"],"enabled":1,"keepCopy":0}' -p cred
|
||||
----
|
||||
or create a json file which contains _{"forwardAddress":["sogo-tests2@sogo.alinto"],"enabled":1,"keepCopy":0}_ then:
|
||||
----
|
||||
sogo-tool user-preferences set defaults user1 Forward -f /path/filename -p cred
|
||||
----
|
||||
|
||||
|
||||
|
||||
Upgrading
|
||||
---------
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ devices (iPhone, iPod touch, and iPad).
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available at
|
||||
https://sogo.nu/downloads/documentation.html.
|
||||
https://www.sogo.nu/support.html#/documentation.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
@@ -22,7 +22,7 @@ Guide_ for more information on installing and configuring SOGo.
|
||||
The instructions are based on version {release_version} of SOGo.
|
||||
|
||||
The latest version of this guide is available
|
||||
at https://sogo.nu/downloads/documentation.html.
|
||||
at https://www.sogo.nu/support.html#/documentation.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
@@ -72,8 +72,14 @@
|
||||
|
||||
- (void) setEndDate: (NSCalendarDate *) newEndDate
|
||||
{
|
||||
CardElement *c;
|
||||
|
||||
[(iCalDateTime *) [self uniqueChildWithTag: @"dtend"]
|
||||
setDateTime: newEndDate];
|
||||
|
||||
c = [self uniqueChildWithTag: @"duration"];
|
||||
if (c)
|
||||
[self removeChild: c];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) endDate
|
||||
|
||||
@@ -44,10 +44,11 @@
|
||||
{
|
||||
NSMutableArray *ranges;
|
||||
NSArray *byMonth;
|
||||
NSCalendarDate *firStart, *lastDate, *rStart, *rEnd, *until, *referenceDate;
|
||||
NSCalendarDate *firStart, *lastDate, *rStart, *rEnd, *until, *referenceDate, *rTemp;
|
||||
NSInteger *hoursOfOffset;
|
||||
iCalMonthlyRecurrenceCalculator *monthlyCalc;
|
||||
unsigned j, yearIdxInRange, numberOfYearsInRange, count, interval, monthDiff;
|
||||
int diff, repeatCount, currentMonth;
|
||||
int diff, repeatCount, currentMonth, origNbDaysInMonth;
|
||||
|
||||
firStart = [firstRange startDate];
|
||||
rStart = [_r startDate];
|
||||
@@ -186,18 +187,31 @@
|
||||
days: 0];
|
||||
|
||||
|
||||
//Due to the bug with dateByAddingYears, we have to take off one day (see line 133)
|
||||
rStart = [NSCalendarDate dateWithYear: [rStart yearOfCommonEra]
|
||||
month: [rStart monthOfYear]
|
||||
day: 0
|
||||
hour: [rStart hourOfDay]
|
||||
minute: [rStart minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [rStart timeZone]];
|
||||
//Due to the bug with dateByAddingYears, we may take the previous day (see line 133)
|
||||
hoursOfOffset = [rStart hourOfDay];
|
||||
origNbDaysInMonth = [rStart numberOfDaysInMonth];
|
||||
if(hoursOfOffset > 12) {
|
||||
//If rStart is 1st 22:00, we should start at the previous day 22:00
|
||||
rTemp = [NSCalendarDate dateWithYear: [rStart yearOfCommonEra]
|
||||
month: 1+([rStart monthOfYear]-2)%12
|
||||
day: 1
|
||||
hour: [rStart hourOfDay]
|
||||
minute: [rStart minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [rStart timeZone]];
|
||||
rStart = [NSCalendarDate dateWithYear: [rStart yearOfCommonEra]
|
||||
month: 1+([rStart monthOfYear]-2)%12
|
||||
day: [rTemp numberOfDaysInMonth]
|
||||
hour: [rStart hourOfDay]
|
||||
minute: [rStart minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [rStart timeZone]];
|
||||
}
|
||||
|
||||
|
||||
rEnd = [rStart dateByAddingYears: 0
|
||||
months: 0
|
||||
days: [rStart numberOfDaysInMonth]];
|
||||
days: origNbDaysInMonth];
|
||||
|
||||
|
||||
rangeForMonth = [NGCalendarDateRange calendarDateRangeWithStartDate: rStart
|
||||
|
||||
@@ -141,7 +141,7 @@ CREATE TABLE sogo_quick_contact (
|
||||
|
||||
CREATE TABLE sogo_sessions_folder (
|
||||
c_id varchar(255) NOT NULL,
|
||||
c_value varchar(255) NOT NULL,
|
||||
c_value varchar(4096) NOT NULL,
|
||||
c_creationdate int(11) NOT NULL,
|
||||
c_lastseen int(11) NOT NULL,
|
||||
PRIMARY KEY (c_id)
|
||||
|
||||
@@ -53,7 +53,7 @@ vtodo_class2 = "(Vertrauliche Aufgabe)";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "Folgendes wurde am Termin \"%{Summary}\" geändert:";
|
||||
"Please accept or decline those changes."
|
||||
= "Bitte akzeptieren Sie diese Änderung, oder lehnen Sie diese ab.";
|
||||
= "Bitte akzeptieren Sie diese Änderungen, oder lehnen Sie diese ab.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Einladung zugestimmt: \"%{Summary}\"";
|
||||
|
||||
@@ -12,9 +12,9 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"The event \"%{Summary}\" was created" = "Įvykis \"%{summary}\" buvo sukurtas";
|
||||
"The event \"%{Summary}\" was deleted" = "Įvykis \"%{Summary}\" buvo ištrintas";
|
||||
"The event \"%{Summary}\" was updated" = "Įvykis \"%{Summary}\" buvo atnaujintas";
|
||||
"The task \"%{Summary}\" was created" = "Įvykis \\"%{summary}\\" buvo sukurtas";
|
||||
"The task \"%{Summary}\" was deleted" = "Įvykis \\"%{Summary}\\" buvo ištrintas";
|
||||
"The task \"%{Summary}\" was updated" = "Įvykis \\"%{Summary}\\" buvo atnaujintas";
|
||||
"The task \"%{Summary}\" was created" = "Įvykis \"%{summary}\" buvo sukurtas";
|
||||
"The task \"%{Summary}\" was deleted" = "Įvykis \"%{Summary}\" buvo ištrintas";
|
||||
"The task \"%{Summary}\" was updated" = "Įvykis \"%{Summary}\" buvo atnaujintas";
|
||||
"The following attendees(s) were notified" = "Šiems dalyviui(iams) buvo pranešta";
|
||||
"The following attendees(s) were added" = "Šie dalyvis(iai) buvo pridėti";
|
||||
"The following attendees(s) were removed" = "Šie dalyvis(iai) buvo pašalinti";
|
||||
@@ -33,13 +33,13 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"attendee_label" = "Dalyvis";
|
||||
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Įvykio pakvietimas: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(išsiųsta nuo %{SentBy}) ";
|
||||
"Event Invitation: \"%{Summary}\"" = "Kvietimas į renginį: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(išsiųsta %{SentBy}) ";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} pakvietė Jus į %{Summary}.\nPradžia: %{StartDate}\nPabaiga: %{EndDate}\nAprašymas: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} pakvietė Jus į %{Summary}.\n\nPradžia: %{StartDate} nuo %{StartTime}\nPabaiga: %{EndDate} nuo %{EndTime}\nAprašymas: %{Description}";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Įvykis atšauktas: \\"%{Summary}\\"";
|
||||
"Event Cancelled: \"%{Summary}\"" = "Įvykis atšauktas: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText} atšaukė šį įvykį: %{Summary}.\n\nPradžia: %{StartDate}\nPabaiga: %{EndDate}\nAprašymas: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
@@ -63,11 +63,11 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText} priėmė Jūsų įvykio pakvietimą.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText} atmetė Jūsų įvykio pakvietimą.";
|
||||
= "%{Attendee} %{SentByText} atmetė Jūsų pakvietimą į renginį.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText} delegavo pakvietimą į %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText} neapsisprendė dėl Jūsų įvykio pakvietimo.";
|
||||
= "%{Attendee} %{SentByText} neapsisprendė dėl Jūsų kvietimo į renginį.";
|
||||
|
||||
/* Reminder */
|
||||
"Reminder: \"%{Summary}\" - %{StartDate}" = "Priminimas: \"%{Summary}\" - %{StartDate}";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
"Personal Address Book" = "Asmeninė adresų knyga";
|
||||
"Collected Address Book" = "Rinktinė adresų knyga";
|
||||
"Collected Address Book" = "Rinktinė adresų knygą";
|
||||
|
||||
@@ -418,7 +418,7 @@ convention:
|
||||
[self setCategories: [o componentsSeparatedByString: @","]];
|
||||
|
||||
// Photo
|
||||
if ([ldifRecord objectForKey: @"photo"])
|
||||
if ([ldifRecord objectForKey: @"photo"] && [ldifRecord objectForKey: @"photo"] != [NSNull null])
|
||||
[self setPhoto: [[ldifRecord objectForKey: @"photo"] stringByEncodingBase64]];
|
||||
|
||||
[self cleanupEmptyChildren];
|
||||
|
||||
@@ -271,6 +271,9 @@ static NSArray *folderListingFields = nil;
|
||||
if ([data length])
|
||||
[contactRecord setObject: data forKey: @"id"];
|
||||
|
||||
// Container name
|
||||
[contactRecord setObject: [self displayName] forKey: @"containerName"];
|
||||
|
||||
// c_cn
|
||||
data = [contactRecord objectForKey: @"c_cn"];
|
||||
if (![data length])
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
//source id
|
||||
[newRecord setObject: [source sourceID] forKey: @"sourceID"];
|
||||
|
||||
//source display name
|
||||
[newRecord setObject: [self displayName]
|
||||
forKey: @"containerName"];
|
||||
|
||||
// c_name => id
|
||||
[newRecord setObject: [oldRecord objectForKey: @"c_name"]
|
||||
forKey: @"c_name"];
|
||||
@@ -430,26 +434,43 @@
|
||||
{
|
||||
NSArray *records, *result;
|
||||
EOSortOrdering *ordering;
|
||||
BOOL processed;
|
||||
|
||||
result = nil;
|
||||
processed = NO;
|
||||
|
||||
if ([filter length] > 0 || ![source listRequiresDot])
|
||||
[source setListRequiresDot: NO];
|
||||
if ( ![source listRequiresDot])
|
||||
{
|
||||
records = [source fetchContactsMatching: filter
|
||||
if ([filter length] > 0) {
|
||||
records = [source fetchContactsMatching: filter
|
||||
withCriteria: criteria
|
||||
inDomain: domain];
|
||||
[childRecords setObjects: records
|
||||
forKeys: [records objectsForKey: @"c_name"
|
||||
notFoundMarker: nil]];
|
||||
records = [self _flattenedRecords: records];
|
||||
ordering
|
||||
= [EOSortOrdering sortOrderingWithKey: sortKey
|
||||
selector: ((sortOrdering == NSOrderedDescending)
|
||||
? EOCompareCaseInsensitiveDescending
|
||||
: EOCompareCaseInsensitiveAscending)];
|
||||
result
|
||||
= [records sortedArrayUsingKeyOrderArray:
|
||||
[NSArray arrayWithObject: ordering]];
|
||||
processed = YES;
|
||||
} else if ([[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesEnabled]) {
|
||||
records = [source fetchContactsMatching: filter
|
||||
withCriteria: criteria
|
||||
inDomain: domain
|
||||
limit: [[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesCount]];
|
||||
processed = YES;
|
||||
}
|
||||
|
||||
if (processed) {
|
||||
[childRecords setObjects: records
|
||||
forKeys: [records objectsForKey: @"c_name"
|
||||
notFoundMarker: nil]];
|
||||
records = [self _flattenedRecords: records];
|
||||
ordering
|
||||
= [EOSortOrdering sortOrderingWithKey: sortKey
|
||||
selector: ((sortOrdering == NSOrderedDescending)
|
||||
? EOCompareCaseInsensitiveDescending
|
||||
: EOCompareCaseInsensitiveAscending)];
|
||||
result
|
||||
= [records sortedArrayUsingKeyOrderArray:
|
||||
[NSArray arrayWithObject: ordering]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
BOOL isHTML;
|
||||
BOOL sign;
|
||||
BOOL encrypt;
|
||||
NSMutableArray *tmpFiles;
|
||||
|
||||
// Used during S/MIME encryption
|
||||
NSMutableDictionary *certificates;
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#import <SOGo/SOGoUserFolder.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/NGMimeFileData+SOGo.h>
|
||||
|
||||
#import <NGCards/NGVCard.h>
|
||||
|
||||
@@ -142,6 +143,7 @@ static NSString *userAgent = nil;
|
||||
isHTML = NO;
|
||||
sign = NO;
|
||||
encrypt = NO;
|
||||
tmpFiles = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -157,6 +159,7 @@ static NSString *userAgent = nil;
|
||||
[sourceFlag release];
|
||||
[inReplyTo release];
|
||||
[references release];
|
||||
[tmpFiles release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -932,7 +935,6 @@ static NSString *userAgent = nil;
|
||||
if (filename)
|
||||
{
|
||||
NSMutableDictionary *currentInfo;
|
||||
|
||||
currentInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
filename, @"filename",
|
||||
mimeType, @"mimetype",
|
||||
@@ -1922,8 +1924,10 @@ static NSString *userAgent = nil;
|
||||
if (_extractImages)
|
||||
{
|
||||
newText = [text htmlByExtractingImages: extractedBodyParts];
|
||||
if ([extractedBodyParts count])
|
||||
if ([extractedBodyParts count]) {
|
||||
[self setText: newText];
|
||||
[self addTmpFiles: extractedBodyParts];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1935,8 +1939,11 @@ static NSString *userAgent = nil;
|
||||
//[self debugWithFormat: @"MIME Envelope: %@", map];
|
||||
allBodyParts = [self bodyPartsForAllAttachments];
|
||||
|
||||
if (!allBodyParts)
|
||||
return nil;
|
||||
if (!allBodyParts) {
|
||||
return nil;
|
||||
} else {
|
||||
[self addTmpFiles: allBodyParts];
|
||||
}
|
||||
|
||||
//[self debugWithFormat: @"attachments: %@", bodyParts];
|
||||
|
||||
@@ -1955,53 +1962,8 @@ static NSString *userAgent = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (_extractImages)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < [extractedBodyParts count] ; i++) {
|
||||
NSMutableDictionary *currentInfo;
|
||||
NSString *filename, *mimeType, *bodyId, *encoding;
|
||||
NSData *body;
|
||||
NGMimeBodyPart *extractedBodyPart;
|
||||
NGMimeContentDispositionHeaderField *contentDisposition;
|
||||
|
||||
extractedBodyPart = [extractedBodyParts objectAtIndex:i];
|
||||
if (extractedBodyPart && [extractedBodyPart headerForKey: @"content-disposition"]) {
|
||||
encoding = [extractedBodyPart encoding];
|
||||
contentDisposition = [[NGMimeContentDispositionHeaderField alloc] initWithString: [extractedBodyPart headerForKey: @"content-disposition"]];
|
||||
|
||||
if (encoding
|
||||
&& [extractedBodyPart contentType]
|
||||
&& [extractedBodyPart contentId]
|
||||
&& [contentDisposition filename]) {
|
||||
|
||||
mimeType = [[extractedBodyPart contentType] stringValue];
|
||||
bodyId = [[extractedBodyPart contentId] stringValue];
|
||||
filename = [contentDisposition filename];
|
||||
currentInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
filename, @"filename",
|
||||
mimeType, @"mimetype",
|
||||
bodyId, @"bodyId",
|
||||
nil];
|
||||
|
||||
if ([[extractedBodyParts objectAtIndex:i] body]) {
|
||||
if (encoding && [encoding rangeOfString:@"base64"].location != NSNotFound)
|
||||
body = [[[extractedBodyParts objectAtIndex:i] body] dataByDecodingBase64];
|
||||
else
|
||||
body = [[extractedBodyParts objectAtIndex:i] body];
|
||||
|
||||
[self saveAttachment: body
|
||||
withMetadata: currentInfo];
|
||||
}
|
||||
}
|
||||
[contentDisposition release];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return a NGMimeMessage object with inline HTML images (<img src=data>) extracted as attachments (<img src=cid>).
|
||||
@@ -2271,6 +2233,41 @@ static NSString *userAgent = nil;
|
||||
return [self sendMailAndCopyToSent: YES];
|
||||
}
|
||||
|
||||
// Extract tmp files in NGMimeBuildMimeTempDirectory from NSArray and store locally
|
||||
// The tmp files will be deleted once the message sent
|
||||
- (void) addTmpFiles:(NSArray *) parts {
|
||||
NGMimeBodyPart *part;
|
||||
|
||||
for (part in parts) {
|
||||
NGMimeFileData *body;
|
||||
NSString *path;
|
||||
|
||||
body = [part body];
|
||||
if (body && [body isKindOfClass: [NGMimeFileData class]]) {
|
||||
path = [body path];
|
||||
if (path) {
|
||||
[tmpFiles addObject: path];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean temporary files
|
||||
- (void) cleanTmpFiles {
|
||||
NSString *path;
|
||||
NSFileManager *fm;
|
||||
|
||||
fm = [NSFileManager defaultManager];
|
||||
|
||||
for (path in tmpFiles) {
|
||||
if ([fm fileExistsAtPath: path])
|
||||
[fm removeFileAtPath: path handler: nil];
|
||||
}
|
||||
|
||||
// Clean tmp files
|
||||
[tmpFiles removeAllObjects];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -2316,8 +2313,10 @@ static NSString *userAgent = nil;
|
||||
inContext: context
|
||||
systemMessage: NO];
|
||||
|
||||
if (error)
|
||||
if (error) {
|
||||
[self cleanTmpFiles];
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// If the current user isn't part of the recipient list for encrypted emails
|
||||
@@ -2376,6 +2375,8 @@ static NSString *userAgent = nil;
|
||||
[imap4 doesMailboxExistAtURL: [container imap4URL]])
|
||||
[(SOGoDraftsFolder *) container expunge];
|
||||
|
||||
[self cleanTmpFiles];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ SOGo_HEADER_FILES = \
|
||||
JWT.h \
|
||||
\
|
||||
NGMimeBodyPart+SOGo.h \
|
||||
NGMimeFileData+SOGo.h \
|
||||
\
|
||||
SOGoMobileProvision.h
|
||||
|
||||
@@ -183,6 +184,7 @@ SOGo_OBJC_FILES = \
|
||||
JWT.m \
|
||||
\
|
||||
NGMimeBodyPart+SOGo.m \
|
||||
NGMimeFileData+SOGo.m \
|
||||
\
|
||||
SOGoMobileProvision.m
|
||||
|
||||
|
||||
+59
-12
@@ -1384,6 +1384,21 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
{
|
||||
if ([match length] > 0) {
|
||||
return [self fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
limit: -1];
|
||||
} else {
|
||||
return [NSMutableArray array];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
limit: (int) limit
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NGLdapConnection *ldapConnection;
|
||||
@@ -1392,6 +1407,8 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
NSMutableArray *contacts;
|
||||
EOQualifier *qualifier;
|
||||
unsigned int i;
|
||||
NSString *sortAttribute;
|
||||
BOOL sortReverse;
|
||||
|
||||
contacts = [NSMutableArray array];
|
||||
|
||||
@@ -1400,18 +1417,48 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
ldapConnection = [self _ldapConnection];
|
||||
qualifier = [self _qualifierForFilter: match onCriteria: criteria];
|
||||
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
if (limit > 0) {
|
||||
[ldapConnection setQuerySizeLimit: limit];
|
||||
}
|
||||
|
||||
if (limit > 0) {
|
||||
// Sort results
|
||||
sortAttribute = @"cn";
|
||||
sortReverse = NO;
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
} else {
|
||||
// No sort results
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
}
|
||||
|
||||
|
||||
i = 0;
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* NGMimeFileData+SOGo.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2023 Alinto
|
||||
*
|
||||
* Author: Sébastien Mizrahi <smizrahi@alinto.eu>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef NGMIMEFILEDATA_SOGO_H
|
||||
#define NGMIMEFILEDATA_SOGO_H
|
||||
|
||||
#import <NGMime/NGMimeFileData.h>
|
||||
|
||||
@interface NGMimeFileData (SOGoExtensions)
|
||||
|
||||
- (NSString *) path;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* NGMIMEFILEDATA_SOGO_H */
|
||||
@@ -0,0 +1,32 @@
|
||||
/* NGMimeFileData+SOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2023 Alinto
|
||||
*
|
||||
* Author: Sébastien Mizrahi <smizrahi@alinto.eu>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "NGMimeFileData+SOGo.h"
|
||||
|
||||
|
||||
@implementation NGMimeFileData (SOGoExtensions)
|
||||
|
||||
- (NSString *) path {
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -65,6 +65,7 @@
|
||||
- (id) objectFromJSONString;
|
||||
|
||||
/* bare email addresses */
|
||||
- (NSString *) mailDomain;
|
||||
- (NSString *) pureEMailAddress;
|
||||
|
||||
- (NSString *) asQPSubjectString: (NSString *) encoding;
|
||||
|
||||
@@ -609,6 +609,18 @@ static int cssEscapingCount;
|
||||
return newString;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) mailDomain
|
||||
{
|
||||
NSArray *mailSeparated;
|
||||
|
||||
mailSeparated = [self componentsSeparatedByString: @"@"];
|
||||
if([mailSeparated count] == 2)
|
||||
return [mailSeparated objectAtIndex: 1];
|
||||
[self logWithFormat: @"Error while extracting domain from : %@", self];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) pureEMailAddress
|
||||
{
|
||||
NSString *pureAddress;
|
||||
@@ -979,6 +991,18 @@ static int cssEscapingCount;
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<ifr***"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove <form
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B	

\\\\0]*f[\\s\\u200B	

\\\\0]*o[\\s\\u200B	

\\\\0]*r[\\s\\u200B	

\\\\0]*m"
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<for*"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove </form
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B	

\\\\0]*/[\\s\\u200B	

\\\\0]*f[\\s\\u200B	

\\\\0]*o[\\s\\u200B	

\\\\0]*r[\\s\\u200B	

\\\\0]*m"
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"</for*"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove onload
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"onload="
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
|
||||
@@ -100,8 +100,19 @@
|
||||
if (data) {
|
||||
if ([data isKindOfClass: [NSString class]])
|
||||
ASSIGN (content, data);
|
||||
else
|
||||
ASSIGN (content, [NSString stringWithUTF8String:[data bytes]]);
|
||||
else {
|
||||
char lastByte;
|
||||
[data getBytes:&lastByte range:NSMakeRange([data length]-1, 1)];
|
||||
if (lastByte == 0x0) {
|
||||
// string is null terminated
|
||||
ASSIGN (content, [NSString stringWithUTF8String: [data bytes]]);
|
||||
} else {
|
||||
// string is not null terminated
|
||||
NSString* myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
ASSIGN (content, myString);
|
||||
[myString release];
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [objectRecord objectForKey: @"c_version"];
|
||||
if (data)
|
||||
|
||||
@@ -123,6 +123,8 @@
|
||||
SOGoTemplatesFolderName = "Templates";
|
||||
SOGoMailComposeMessageType = "html";
|
||||
SOGoMailComposeFontSize = "0";
|
||||
SOGoMailHideInlineAttachments = NO;
|
||||
SOGoMailDisplayFullEmail = NO;
|
||||
SOGoMailDisplayRemoteInlineImages = "never";
|
||||
SOGoMailCertificateEnabled = YES;
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
v = [self integerForKey: @"SOGoForwardConstraints"];
|
||||
|
||||
return (v > 2 ? 0 : v);
|
||||
return (v > 3 ? 0 : v);
|
||||
}
|
||||
|
||||
- (NSArray *) forwardConstraintsDomains
|
||||
|
||||
@@ -739,7 +739,8 @@ static NSArray *childRecordFields = nil;
|
||||
qualifier = aclQualifier;
|
||||
|
||||
// For Thunderbird, disable contact list
|
||||
if ([[context request] isThunderbird]) {
|
||||
// This will be removed when VCARD will be implemented
|
||||
if ([[context request] isThunderbird] && [self isKindOfClass: NSClassFromString(@"SOGoContactGCSFolder")]) {
|
||||
vlistExclusionQualifier = [EOQualifier qualifierWithQualifierFormat: @"c_component != 'vlist'"];
|
||||
qualifier = [[[EOAndQualifier alloc] initWithQualifiers:
|
||||
vlistExclusionQualifier,
|
||||
@@ -1191,7 +1192,8 @@ static NSArray *childRecordFields = nil;
|
||||
folder = [self ocsFolder];
|
||||
|
||||
// For Thunderbird, disable contact list
|
||||
if ([[context request] isThunderbird]) {
|
||||
// This will be removed when VCARD will be implemented
|
||||
if ([[context request] isThunderbird] && [self isKindOfClass: NSClassFromString(@"SOGoContactGCSFolder")]) {
|
||||
vlistExclusionQualifier = [EOQualifier qualifierWithQualifierFormat: @"c_component != 'vlist'"];
|
||||
qualifier = [[[EOAndQualifier alloc] initWithQualifiers:
|
||||
vlistExclusionQualifier,
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
NSDictionary *provisioning;
|
||||
NSError *error;
|
||||
NSString *payloadType, *prefix, *type;
|
||||
NSNumber *port;
|
||||
|
||||
activeUser = [context activeUser];
|
||||
serverURL = [context serverURL];
|
||||
@@ -57,11 +58,20 @@
|
||||
break;
|
||||
}
|
||||
|
||||
port = [serverURL port];
|
||||
if (!port) {
|
||||
if ([[serverURL scheme] isEqualToString:@"https"]) {
|
||||
port = [NSNumber numberWithInt: 443];
|
||||
} else {
|
||||
port = [NSNumber numberWithInt: 80];
|
||||
}
|
||||
}
|
||||
|
||||
provisioning = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSArray arrayWithObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithFormat:@"%@ %@", type, name], [NSString stringWithFormat:@"%@%@", prefix, @"AccountDescription"],
|
||||
[serverURL host], [NSString stringWithFormat:@"%@%@", prefix, @"HostName"],
|
||||
[serverURL port], [NSString stringWithFormat:@"%@%@", prefix, @"Port"],
|
||||
port, [NSString stringWithFormat:@"%@%@", prefix, @"Port"],
|
||||
path, [NSString stringWithFormat:@"%@%@", prefix, @"PrincipalURL"],
|
||||
[NSNumber numberWithBool:[[serverURL scheme] isEqualToString:@"https"]], [NSString stringWithFormat:@"%@%@", prefix, @"UseSSL"],
|
||||
[activeUser login], [NSString stringWithFormat:@"%@%@", prefix, @"Username"],
|
||||
|
||||
@@ -33,7 +33,7 @@ static const NSString *POLICY_MIN_DIGIT = @"POLICY_MIN_DIGIT";
|
||||
static const NSString *POLICY_MIN_SPECIAL_SYMBOLS = @"POLICY_MIN_SPECIAL_SYMBOLS";
|
||||
static const NSString *POLICY_MIN_LENGTH = @"POLICY_MIN_LENGTH";
|
||||
|
||||
static const NSString *SPECIAL_SYMBOL_ALLOWED = @"%$&*(){}!?\\@#.,:;+=";
|
||||
static const NSString *SPECIAL_SYMBOL_ALLOWED = @"%$&*(){}!?\\@#.,:;+=\\[\\]\\|<>\\/-_";
|
||||
|
||||
@implementation SOGoPasswordPolicy
|
||||
|
||||
|
||||
@@ -102,10 +102,12 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
EOAdaptorChannel *channel;
|
||||
NSDictionary *row;
|
||||
NSException *ex;
|
||||
NSString *sql, *value;
|
||||
NSString *sql, *result;
|
||||
id value;
|
||||
NSArray *attrs;
|
||||
|
||||
value = nil;
|
||||
result = nil;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
channel = [cm acquireOpenChannelForURL: tableURL];
|
||||
@@ -136,6 +138,12 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
value = [row objectForKey: fieldName];
|
||||
if (![value isNotNull])
|
||||
value = nil; /* we discard any NSNull instance */
|
||||
|
||||
if (value && [value isKindOfClass: [NSData class]]) {
|
||||
result = [NSString stringWithUTF8String: [value bytes]];
|
||||
} else if (value && [value isKindOfClass: [NSString class]]) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
[cm releaseChannel: channel];
|
||||
@@ -147,7 +155,7 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
tableURL];
|
||||
}
|
||||
|
||||
return value;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *) generateSQLForInsert: (NSString *) jsonRepresentation
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain;
|
||||
- (NSArray *)fetchContactsMatching:(NSString *)filter
|
||||
withCriteria:(NSArray *)criteria
|
||||
inDomain:(NSString *)domain
|
||||
limit:(int)limit;
|
||||
|
||||
- (NSArray *) lookupContactsWithQualifier: (EOQualifier *) qualifier
|
||||
andSortOrdering: (EOSortOrdering *) ordering
|
||||
inDomain: (NSString *) domain;
|
||||
|
||||
@@ -130,6 +130,11 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
|
||||
- (NSString *) JWTSecret;
|
||||
|
||||
- (NSArray *) disableSharing;
|
||||
- (NSArray *) disableSharingAnyAuthUser;
|
||||
- (NSArray *) disableExport;
|
||||
|
||||
- (BOOL) enableGlobalAddressBookFirstEntries;
|
||||
- (int) globalAddressBookFirstEntriesCount;
|
||||
|
||||
- (BOOL)isURLEncryptionEnabled;
|
||||
- (NSString *)urlEncryptionPassphrase;
|
||||
|
||||
@@ -835,4 +835,47 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
|
||||
return passphrase;
|
||||
}
|
||||
|
||||
- (NSArray *) disableSharingAnyAuthUser
|
||||
{
|
||||
static NSArray *disableSharingAnyAuthUser = nil;
|
||||
|
||||
if (!disableSharingAnyAuthUser)
|
||||
{
|
||||
disableSharingAnyAuthUser = [self stringArrayForKey: @"SOGoDisableSharingAnyAuthUser"];
|
||||
[disableSharingAnyAuthUser retain];
|
||||
}
|
||||
|
||||
return disableSharingAnyAuthUser;
|
||||
}
|
||||
|
||||
- (NSArray *) disableExport
|
||||
{
|
||||
static NSArray *disableExport = nil;
|
||||
|
||||
if (!disableExport)
|
||||
{
|
||||
disableExport = [self stringArrayForKey: @"SOGoDisableExport"];
|
||||
[disableExport retain];
|
||||
}
|
||||
|
||||
return disableExport;
|
||||
}
|
||||
|
||||
- (BOOL) globalAddressBookFirstEntriesEnabled
|
||||
{
|
||||
return [self boolForKey: @"SOGoGlobalAddressBookFirstEntries"];
|
||||
}
|
||||
|
||||
- (int) globalAddressBookFirstEntriesCount
|
||||
{
|
||||
int v;
|
||||
|
||||
v = [self integerForKey: @"SOGoGlobalAddressBookFirstEntriesCount"];
|
||||
|
||||
if (!v)
|
||||
v = 100;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -156,6 +156,9 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
|
||||
- (void) setMailComposeFontSize: (int) newValue;
|
||||
- (int) mailComposeFontSize;
|
||||
|
||||
- (void) setMailDisplayFullEmail: (BOOL *) newValue;
|
||||
- (BOOL *) mailDisplayFullEmail;
|
||||
|
||||
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue;
|
||||
- (NSString *) mailDisplayRemoteInlineImages;
|
||||
|
||||
@@ -228,8 +231,11 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
|
||||
- (void) setMailLabelsColors: (NSDictionary *) newValues;
|
||||
- (NSDictionary *) mailLabelsColors;
|
||||
|
||||
- (void)setHideInlineAttachments:(BOOL)newValue;
|
||||
- (BOOL)hideInlineAttachments;
|
||||
|
||||
/* calendar */
|
||||
- (void) setCalendarCategories: (NSArray *) newValues;
|
||||
- (void)setCalendarCategories : (NSArray *)newValues;
|
||||
- (NSArray *) calendarCategories;
|
||||
|
||||
- (void) setCalendarCategoriesColors: (NSDictionary *) newValues;
|
||||
|
||||
@@ -631,6 +631,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
|
||||
return [self integerForKey: @"SOGoMailComposeFontSize"];
|
||||
}
|
||||
|
||||
- (void) setMailDisplayFullEmail: (BOOL *) newValue
|
||||
{
|
||||
[self setBool: newValue forKey: @"SOGoMailDisplayFullEmail"];
|
||||
}
|
||||
|
||||
- (BOOL *) mailDisplayFullEmail;
|
||||
{
|
||||
return [self boolForKey: @"SOGoMailDisplayFullEmail"];
|
||||
}
|
||||
|
||||
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue
|
||||
{
|
||||
[self setObject: newValue forKey: @"SOGoMailDisplayRemoteInlineImages"];
|
||||
@@ -959,6 +969,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
|
||||
return [self objectForKey: @"SOGoMailLabelsColors"];
|
||||
}
|
||||
|
||||
- (void) setHideInlineAttachments: (BOOL) newValue
|
||||
{
|
||||
[self setBool: newValue forKey: @"SOGoMailHideInlineAttachments"];
|
||||
}
|
||||
|
||||
- (BOOL) hideInlineAttachments
|
||||
{
|
||||
return [self boolForKey: @"SOGoMailHideInlineAttachments"];
|
||||
}
|
||||
|
||||
- (void) setSieveFilters: (NSArray *) newValue
|
||||
{
|
||||
[self setObject: newValue forKey: @"SOGoSieveFilters"];
|
||||
|
||||
@@ -924,6 +924,22 @@
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain
|
||||
|
||||
{
|
||||
if ([filter length] > 0) {
|
||||
return [self fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain
|
||||
limit: -1];
|
||||
} else {
|
||||
return [NSMutableArray array];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)fetchContactsMatching: (NSString *)filter
|
||||
withCriteria: (NSArray *)criteria
|
||||
inDomain: (NSString *)domain
|
||||
limit: (int)limit
|
||||
{
|
||||
EOAdaptorChannel *channel;
|
||||
NSEnumerator *criteriaList;
|
||||
@@ -994,6 +1010,8 @@
|
||||
[sql appendFormat: @" AND %@ IS NULL", _domainField];
|
||||
}
|
||||
|
||||
if (limit > 0)
|
||||
[sql appendFormat: @" ORDER BY c_cn ASC LIMIT %i", limit];
|
||||
ex = [channel evaluateExpressionX: sql];
|
||||
if (!ex)
|
||||
{
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
testEquals([[NSString stringWithString:@"<img vbscript:test"] stringWithoutHTMLInjection: NO], @"<img test");
|
||||
testEquals([[NSString stringWithString:@"<img javascript:test"] stringWithoutHTMLInjection: NO], @"<img test");
|
||||
testEquals([[NSString stringWithString:@"<img livescript:test"] stringWithoutHTMLInjection: NO], @"<img test");
|
||||
testEquals([[NSString stringWithString:@"foobar <form action=\"\">bar</form>"] stringWithoutHTMLInjection: NO], @"foobar <for* action=\"\">bar</for*>");
|
||||
testEquals([[NSString stringWithString:@"foobar <iframe src=\"\">bar</iframe>"] stringWithoutHTMLInjection: NO], @"foobar <ifr*** src=\"\">bar</iframe>");
|
||||
testEquals([[NSString stringWithString:@"foobar <img onload=foo bar"] stringWithoutHTMLInjection: NO], @"foobar <img onl***=foo bar");
|
||||
testEquals([[NSString stringWithString:@"foobar <img onmouseover=foo bar"] stringWithoutHTMLInjection: NO], @"foobar <img onmouseo***=foo bar");
|
||||
|
||||
+70
-70
@@ -221,95 +221,95 @@
|
||||
count = [objects count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
content = [[[objects objectAtIndex: i] objectForKey: @"c_content"] stringByTrimmingSpaces];
|
||||
c_name = [[objects objectAtIndex: i] objectForKey: @"c_name"];
|
||||
if (is_calendar)
|
||||
{
|
||||
// We check for
|
||||
// BEGIN:VCALENDAR
|
||||
// ..
|
||||
// END:VCALENDAR
|
||||
iCalCalendar *calendar;
|
||||
{
|
||||
content = [[[objects objectAtIndex: i] objectForKey: @"c_content"] stringByTrimmingSpaces];
|
||||
c_name = [[objects objectAtIndex: i] objectForKey: @"c_name"];
|
||||
if (is_calendar)
|
||||
{
|
||||
// We check for
|
||||
// BEGIN:VCALENDAR
|
||||
// ..
|
||||
// END:VCALENDAR
|
||||
iCalCalendar *calendar;
|
||||
|
||||
if ([content length] < 30 ||
|
||||
if ([content length] < 30 ||
|
||||
[[content substringToIndex: 15] caseInsensitiveCompare: @"BEGIN:VCALENDAR"] != NSOrderedSame ||
|
||||
[[content substringFromIndex: [content length]-13] caseInsensitiveCompare: @"END:VCALENDAR"] != NSOrderedSame)
|
||||
{
|
||||
NSLog(@"Corrupted calendar item (missing tags) in path %@ with c_name = %@", folder, c_name);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
calendar = [iCalCalendar parseSingleFromSource: content];
|
||||
if (!calendar)
|
||||
{
|
||||
NSLog(@"Corrupted calendar item (unparsable) in path %@ with c_name = %@", folder, c_name);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
iCalEvent *event;
|
||||
{
|
||||
NSLog(@"Corrupted calendar item (unparsable) in path %@ with c_name = %@", folder, c_name);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = (iCalEvent *) [calendar firstChildWithTag: @"vevent"];
|
||||
if (event)
|
||||
{
|
||||
iCalDateTime *startDate, *endDate;
|
||||
event = (iCalEvent *) [calendar firstChildWithTag: @"vevent"];
|
||||
if (event)
|
||||
{
|
||||
iCalDateTime *startDate, *endDate;
|
||||
|
||||
startDate = (iCalDateTime *) [event uniqueChildWithTag: @"dtstart"];
|
||||
if (![startDate dateTime])
|
||||
{
|
||||
NSLog(@"Missing start date of event in path %@ with c_name = %@ (%@)", folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
endDate = (iCalDateTime *) [event uniqueChildWithTag: @"dtend"];
|
||||
if (![endDate dateTime] && ![event hasDuration])
|
||||
{
|
||||
NSLog(@"Missing end date of event in path %@ with c_name = %@ (%@)", folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
if ([startDate dateTime] && [endDate dateTime])
|
||||
{
|
||||
NSComparisonResult comparison;
|
||||
startDate = (iCalDateTime *) [event uniqueChildWithTag: @"dtstart"];
|
||||
if (![startDate dateTime])
|
||||
{
|
||||
NSLog(@"Missing start date of event in path %@ with c_name = %@ (%@)", folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
endDate = (iCalDateTime *) [event uniqueChildWithTag: @"dtend"];
|
||||
if (![endDate dateTime] && ![event hasDuration])
|
||||
{
|
||||
NSLog(@"Missing end date of event in path %@ with c_name = %@ (%@)", folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
if ([startDate dateTime] && [endDate dateTime])
|
||||
{
|
||||
NSComparisonResult comparison;
|
||||
|
||||
comparison = [[startDate dateTime] compare: [endDate dateTime]];
|
||||
if (([event isAllDay] && comparison == NSOrderedDescending) ||
|
||||
(![event isAllDay] && comparison != NSOrderedAscending))
|
||||
{
|
||||
NSLog(@"Start date (%@) is not before end date (%@) for event in path %@ with c_name = %@ (%@)",
|
||||
[startDate dateTime], [endDate dateTime], folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
comparison = [[startDate dateTime] compare: [endDate dateTime]];
|
||||
if (([event isAllDay] && comparison == NSOrderedDescending) ||
|
||||
(![event isAllDay] && comparison != NSOrderedAscending))
|
||||
{
|
||||
NSLog(@"Start date (%@) is not before end date (%@) for event in path %@ with c_name = %@ (%@)",
|
||||
[startDate dateTime], [endDate dateTime], folder, c_name, [event summary]);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NGVCard *card;
|
||||
}
|
||||
else
|
||||
{
|
||||
NGVCard *card;
|
||||
|
||||
card = [NGVCard parseSingleFromSource: content];
|
||||
card = [NGVCard parseSingleFromSource: content];
|
||||
|
||||
if (!card)
|
||||
if (!card)
|
||||
{
|
||||
NSLog(@"Corrupted card item (unparsable) in path %@ with c_name = %@", folder, c_name);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
NSLog(@"Corrupted card item (unparsable) in path %@ with c_name = %@", folder, c_name);
|
||||
if (delete)
|
||||
[gcsFolder deleteContentWithName: c_name];
|
||||
rc = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,14 @@
|
||||
sessionExpireMinutes = [[arguments objectAtIndex: 0] intValue];
|
||||
}
|
||||
|
||||
if (sessionExpireMinutes >= 0)
|
||||
NSLog(@"Remove all sessions older than %d min", sessionExpireMinutes);
|
||||
|
||||
if (sessionExpireMinutes == 0 && ![[arguments objectAtIndex: 0] isEqualToString:@"0"])
|
||||
{
|
||||
//If the input is not a number intValue return 0 so we check that's really the case
|
||||
[self usage];
|
||||
}
|
||||
else if (sessionExpireMinutes >= 0)
|
||||
{
|
||||
rc = [self expireUserSessionOlderThan: sessionExpireMinutes];
|
||||
}
|
||||
|
||||
@@ -113,13 +113,13 @@ typedef enum
|
||||
" remove remove all ACL information of folder for user\n"
|
||||
" subscribe subscribe user to owner's folder\n"
|
||||
" unsubscribe unsubscribe user to owner's folder\n"
|
||||
" owner the user owning the folder\n"
|
||||
" owner the user owning the folder\n"
|
||||
" folder the folder - Calendar/<ID> or Contacts/<ID>\n"
|
||||
" user the user (or group without the @ prefix) to get/set rights for - 'ALL', '<default>', 'anonymous' are supported\n"
|
||||
" rights rights to add\n\n"
|
||||
"Example: sogo-tool manage-acl get jdoe Calendar/personal ALL\n\n"
|
||||
"Note: You can add only one access right at the time. To set them all at once,\n"
|
||||
" invoke 'remove' first to remove them all.\n\n");
|
||||
" rights rights to add\n\n"
|
||||
"Example: sogo-tool manage-acl get jdoe Calendar/personal ALL\n\n"
|
||||
"Note: You can add only one access right at the time. To set them all at once,\n"
|
||||
" invoke 'remove' first to remove them all.\n\n");
|
||||
}
|
||||
|
||||
- (BOOL) parseArguments
|
||||
|
||||
@@ -86,15 +86,15 @@
|
||||
/* we want to match the field value case-insensitively */
|
||||
recordEmail = [[record objectForKey: field] uppercaseString];
|
||||
if ([recordEmail length])
|
||||
{
|
||||
recordList = [doubleEmails objectForKey: recordEmail];
|
||||
if (!recordList)
|
||||
{
|
||||
recordList = [doubleEmails objectForKey: recordEmail];
|
||||
if (!recordList)
|
||||
{
|
||||
recordList = [NSMutableArray arrayWithCapacity: 5];
|
||||
[doubleEmails setObject: recordList forKey: recordEmail];
|
||||
}
|
||||
[recordList addObject: record];
|
||||
recordList = [NSMutableArray arrayWithCapacity: 5];
|
||||
[doubleEmails setObject: recordList forKey: recordEmail];
|
||||
}
|
||||
[recordList addObject: record];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) cleanupSingleRecords: (NSMutableDictionary *) doubleEmails
|
||||
@@ -220,21 +220,20 @@
|
||||
|
||||
recordsToRemove = [NSMutableArray arrayWithCapacity: (max - 1)];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
if (count != keptRecord)
|
||||
{
|
||||
if (count != keptRecord)
|
||||
{
|
||||
currentRecord = [records objectAtIndex: count];
|
||||
[recordsToRemove
|
||||
addObject: [currentRecord objectForKey: @"c_name"]];
|
||||
}
|
||||
currentRecord = [records objectAtIndex: count];
|
||||
[recordsToRemove addObject: [currentRecord objectForKey: @"c_name"]];
|
||||
}
|
||||
}
|
||||
|
||||
return recordsToRemove;
|
||||
}
|
||||
|
||||
- (NSArray *) records: (NSArray *) records
|
||||
withLowestScores: (unsigned int *) scores
|
||||
count: (unsigned int) max
|
||||
count: (unsigned int) max
|
||||
{
|
||||
unsigned int count, highestScore;
|
||||
int highestScoreRecord;
|
||||
@@ -242,13 +241,13 @@
|
||||
highestScore = 0;
|
||||
highestScoreRecord = -1;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
if (scores[count] > highestScore)
|
||||
{
|
||||
if (scores[count] > highestScore)
|
||||
{
|
||||
highestScore = scores[count];
|
||||
highestScoreRecord = count;
|
||||
}
|
||||
highestScore = scores[count];
|
||||
highestScoreRecord = count;
|
||||
}
|
||||
}
|
||||
|
||||
if (highestScoreRecord == -1)
|
||||
highestScoreRecord = 0;
|
||||
@@ -268,16 +267,15 @@
|
||||
|
||||
highestVersion = 0;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentVersion = [[records objectAtIndex: count] objectForKey: @"c_version"];
|
||||
version = [currentVersion intValue];
|
||||
if (version > highestVersion)
|
||||
{
|
||||
currentVersion
|
||||
= [[records objectAtIndex: count] objectForKey: @"c_version"];
|
||||
version = [currentVersion intValue];
|
||||
if (version > highestVersion)
|
||||
{
|
||||
mostModified = count;
|
||||
highestVersion = version;
|
||||
}
|
||||
mostModified = count;
|
||||
highestVersion = version;
|
||||
}
|
||||
}
|
||||
|
||||
return mostModified;
|
||||
}
|
||||
@@ -291,25 +289,25 @@
|
||||
amount = 0;
|
||||
|
||||
if (!quickFields)
|
||||
{
|
||||
quickFields = [NSArray arrayWithObjects: @"c_givenname", @"c_cn",
|
||||
@"c_sn", @"c_screenname", @"c_l", @"c_mail",
|
||||
@"c_o", @"c_ou", @"c_telephonenumber", nil];
|
||||
[quickFields retain];
|
||||
}
|
||||
{
|
||||
quickFields = [NSArray arrayWithObjects: @"c_givenname", @"c_cn",
|
||||
@"c_sn", @"c_screenname", @"c_l", @"c_mail",
|
||||
@"c_o", @"c_ou", @"c_telephonenumber", nil];
|
||||
[quickFields retain];
|
||||
}
|
||||
|
||||
max = [quickFields count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
value = [record objectForKey: [quickFields objectAtIndex: count]];
|
||||
if ([value isKindOfClass: [NSString class]])
|
||||
{
|
||||
value = [record objectForKey: [quickFields objectAtIndex: count]];
|
||||
if ([value isKindOfClass: [NSString class]])
|
||||
{
|
||||
if ([value length])
|
||||
amount++;
|
||||
}
|
||||
else if ([value isKindOfClass: [NSNumber class]])
|
||||
amount++;
|
||||
if ([value length])
|
||||
amount++;
|
||||
}
|
||||
else if ([value isKindOfClass: [NSNumber class]])
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
@@ -323,15 +321,14 @@
|
||||
|
||||
highestQFields = 0;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentQFields = [self amountOfFilledQuickFields: [records objectAtIndex: count]];
|
||||
if (currentQFields > highestQFields)
|
||||
{
|
||||
currentQFields
|
||||
= [self amountOfFilledQuickFields: [records objectAtIndex: count]];
|
||||
if (currentQFields > highestQFields)
|
||||
{
|
||||
mostQuickFields = count;
|
||||
highestQFields = currentQFields;
|
||||
}
|
||||
mostQuickFields = count;
|
||||
highestQFields = currentQFields;
|
||||
}
|
||||
}
|
||||
|
||||
return mostQuickFields;
|
||||
}
|
||||
@@ -399,10 +396,28 @@
|
||||
}
|
||||
|
||||
- (void) assignScores: (unsigned int *) scores
|
||||
toRecords: (NSArray *) records
|
||||
count: (unsigned int) max
|
||||
toRecords: (NSArray *) records
|
||||
count: (unsigned int) max
|
||||
withCardsInLists: (NSArray *) cardsInLists
|
||||
{
|
||||
/*
|
||||
Records is an Array of record which are duplicates of each other.
|
||||
The goal here is to know which one to keep and whoch ones to discard.
|
||||
We will assign a score to each record, the one with the best scores is kept
|
||||
Record which has been the last modified: +1
|
||||
Record has the most content: +2
|
||||
Record has the most quick field set: +3
|
||||
Record is in a list: +6
|
||||
|
||||
If two record have the same, for exemple, content. It's the first one on the list
|
||||
that will get the points.
|
||||
If two recors have the same score. t's the first one on the list
|
||||
that will get the points.
|
||||
|
||||
quick fiels are =("c_givenname": Firstname, @"c_cn": Display,
|
||||
@"c_sn": LastName, @"c_screenname": Screen Name @"c_l": City, @"c_mail": mails,
|
||||
@"c_o": organisation, @"c_ou": organisation unit, @"c_telephonenumber": telephone)
|
||||
*/
|
||||
int recordIndex;
|
||||
|
||||
recordIndex = [self mostModifiedRecord: records count: max];
|
||||
|
||||
@@ -634,7 +634,7 @@
|
||||
|
||||
if (authname == nil || authpwd == nil)
|
||||
{
|
||||
NSLog(@"To update Sieve scripts, you must provide the \"-p credentialFile\" parameter");
|
||||
NSLog(@"To update Sieve scripts, you must provide the \"-c credentialFile\" parameter");
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,8 +210,7 @@
|
||||
GCSFolder *folder;
|
||||
BOOL rc;
|
||||
|
||||
folderPath = [NSString stringWithFormat: @"/Users/%@/Calendar/%@",
|
||||
username, folderId];
|
||||
folderPath = [NSString stringWithFormat: @"/Users/%@/Calendar/%@", username, folderId];
|
||||
folder = [fom folderAtPath: folderPath];
|
||||
if (folder)
|
||||
rc = [self truncateEntriesFromFolder: folder usingDate: date];
|
||||
@@ -238,12 +237,13 @@
|
||||
// in the default timezone.
|
||||
s = [NSString stringWithFormat: @"%@ GMT", date];
|
||||
d = [NSCalendarDate dateWithString: s calendarFormat: @"%Y-%m-%dT%H:%M:%S %Z"];
|
||||
NSLog(@"Date is: %@", d);
|
||||
fom = [GCSFolderManager defaultFolderManager];
|
||||
|
||||
if (d && fom)
|
||||
rc = [self processFolder: folder
|
||||
ofUser: username
|
||||
date: d
|
||||
date: d
|
||||
withFoM: fom];
|
||||
else
|
||||
rc = NO;
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
[helpString appendFormat: @"\t%-20@-- %@\n",
|
||||
command, [currentTool objectAtIndex: 1]];
|
||||
}
|
||||
[helpString appendString: @"\n Visit https://www.sogo.nu/files/docs/SOGoInstallationGuide.html#_using_sogo_tool to get more infos"];
|
||||
|
||||
|
||||
|
||||
NSLog (@"%@", helpString);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Help" = "Pagalba";
|
||||
"Close" = "Uždarytis";
|
||||
"Close" = "Uždaryti";
|
||||
"Modules" = "Moduliai";
|
||||
/* Modules short names */
|
||||
"ACLs" = "ACLs";
|
||||
@@ -14,7 +14,7 @@
|
||||
/* Rights module: initial search message */
|
||||
"Start a search to edit the rights" = "Pradėti paiešką redaguoti savo teisėms";
|
||||
/* Rights module: Empty search result */
|
||||
"No matching user" = "Nerasta atitinkantis vartotojas";
|
||||
"No matching user" = "Nėra atitinkamo naudotojo";
|
||||
/* Rights module: no selection */
|
||||
"No resource selected" = "Nėra pasirinkta išteklių";
|
||||
"Add User" = "Pridėti vartotoją";
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"Reduce" = "Reduzir";
|
||||
|
||||
/* tooltip */
|
||||
"Refresh" = "Refresh";
|
||||
"Refresh" = "Atualizar";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
@@ -109,7 +109,7 @@
|
||||
"Personal" = "Pessoal";
|
||||
"To Do" = "Tarefa";
|
||||
"Later" = "Adiar";
|
||||
"Forwarded" = "Forwarded";
|
||||
"Forwarded" = "Encaminhado";
|
||||
"Return Receipt Sent" = "Confirmação de recebimento enviada";
|
||||
"a2_Sunday" = "Dom";
|
||||
"a2_Monday" = "Seg";
|
||||
@@ -227,9 +227,9 @@
|
||||
"Move forward" = "Mover para frente";
|
||||
|
||||
/* Password Recovery */
|
||||
"passwordRecovery_Disabled" = "Disabled";
|
||||
"passwordRecovery_SecretQuestion" = "Secret question";
|
||||
"passwordRecovery_SecretQuestion1" = "What is the name of your first pet ?";
|
||||
"passwordRecovery_SecretQuestion2" = "What was your first car ?";
|
||||
"passwordRecovery_SecretQuestion3" = "What is your favorite movie ?";
|
||||
"passwordRecovery_SecondaryEmail" = "Secondary E-mail";
|
||||
"passwordRecovery_Disabled" = "Desabilitado";
|
||||
"passwordRecovery_SecretQuestion" = "Pergunta secreta";
|
||||
"passwordRecovery_SecretQuestion1" = "Qual é o nome do seu primeiro animal de estimação?";
|
||||
"passwordRecovery_SecretQuestion2" = "Qual foi o seu primeiro carro?";
|
||||
"passwordRecovery_SecretQuestion3" = "Qual é o seu filme favorito ?";
|
||||
"passwordRecovery_SecondaryEmail" = "E-mail secundário";
|
||||
|
||||
@@ -26,15 +26,15 @@
|
||||
"Subscribe User" = "Prenumeruoti vartotoją";
|
||||
"Any Authenticated User" = "Bet kokiam autentifikuotam vartotojui";
|
||||
"Public Access" = "Vieša prieiga";
|
||||
"Any user not listed above" = "Bet kuris vartotojas, nesantis aukščiau išvardytų";
|
||||
"Anybody accessing this resource from the public area" = "Kas nors jungiansi prie šio šaltinio iš viešos erdvės";
|
||||
"Sorry, the user rights can not be configured for that object." = "Atsiprašome, vartotojo teisės negali būti konfiguruojamos šiam objektui.";
|
||||
"Any user not listed above" = "Bet kuris pirmiau nenurodytas naudotojas";
|
||||
"Anybody accessing this resource from the public area" = "Visi, kurie prie šio ištekliaus prieina iš viešosios erdvės.";
|
||||
"Sorry, the user rights can not be configured for that object." = "Atsiprašome, naudotojo teisių šiam objektui konfigūruoti negalima.";
|
||||
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
|
||||
= "Bet kuris vartotojas turintis paskyrą šioje sistemoje galės prieiti prie Jūsų elektroninės pašto dėžutės \"%{0}\". Ar Jūs tikrai jais pasitikite?";
|
||||
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
|
||||
= "Bet kuris vartotojas turintis paskyrą šioje sistemoje galės prieiti prie Jūsų kalendoriaus \"%{0}\". Ar Jūs tikrai jais pasitikite?";
|
||||
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
= "Potencialiai visi internete galės prieiti prie Jūsų kalendoriaus \"%{0}\", net jei jie ir neturi paskyros šioje sistemoje. Ar ši informacija tinka viešai prieigai?";
|
||||
= "Prie Jūsų kalendoriaus \"%{0}\" galės prieiti bet kuris internete esantis asmuo, net jei jis neturi paskyros šioje sistemoje. Ar ši informacija tinka viešai prieigai?";
|
||||
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
|
||||
= "Visi vartotojai turintys paskyras šioje sistemoje galės prieiti prie adresų knygos \"%{0}\". Ar Jūs tikrai jais pasitikite?";
|
||||
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
@@ -51,29 +51,29 @@
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Neįmanoma prenumeruoti šio aplanko!";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Jūs negalite prenumeruoti savo aplanko!";
|
||||
= "Jūs negalite prenumeruoti Jums priklausančio aplanko!";
|
||||
"Unable to unsubscribe from that folder!"
|
||||
= "Negalima neprenumeruoti iš šio aplanko!";
|
||||
= "Nepavyksta atsisakyti prenumeratos šiame aplanke!";
|
||||
"You cannot unsubscribe from a folder that you own!"
|
||||
= "Jūs negalite neprenumeruoti savo aplanko!";
|
||||
= "Negalite atsisakyti prenumeratos iš Jums priklausančio aplanko!";
|
||||
"Unable to rename that folder!" = "Negalima pervardinti aplanko!";
|
||||
"You have already subscribed to that folder!"
|
||||
= "Jūs jau prenumeruojate šį aplanką!";
|
||||
= "Jūs jau užsiprenumeravote šį aplanką!";
|
||||
"The user rights cannot be edited for this object!"
|
||||
= "Vartotojo teisės negali būti keičiamos šiam objektui!";
|
||||
"A folder by that name already exists." = "Aplankas tokiu pavadinimu jau egzistuoja.";
|
||||
"You cannot create a list in a shared address book."
|
||||
= "Jūs negalite sukurti sąrašo pasidalintoje adresų knygoje.";
|
||||
= "Bendrai naudojamoje adresų knygoje negalima sukurti sąrašo.";
|
||||
"Warning" = "Įspėjimas";
|
||||
"Can't contact server" = "Įvyko klaida, kai buvo bandoma susisiekti su serveriu. Prašome bandyti dar kartą.";
|
||||
"You are not allowed to access this module or this system. Please contact your system administrator."
|
||||
= "Jums negalima prieiti prie šio modulio ar šios sistemos. Prašome susisiekti su Jūsų sistemos administratoriumi.";
|
||||
"You don't have the required privileges to perform the operation."
|
||||
= "Jūs neturite reikalingų teisių atlikti šiam veiksmui.";
|
||||
"noEmailForDelegation" = "Jūs turite nurodyti adresą, kurį norite perduoti Jūsų kvietime.";
|
||||
= "Neturite reikalingų teisių šiam veiksmui atlikti.";
|
||||
"noEmailForDelegation" = "Turite nurodyti adresą, kuriam norite perduoti kvietimą.";
|
||||
"delegate is organizer" = "Atstovas yra kelionių organizatorius. Prašome nurodyti kitą ";
|
||||
"delegate is a participant" = "Atstovas jau yra dalyvis.";
|
||||
"delegate is a group" = "Nurodytas adresas atitinka grupę. Jūs galite tik atstovauti unikalų asmenį.";
|
||||
"delegate is a group" = "Nurodytas adresas atitinka grupę. Deleguoti galima tik unikaliam asmeniui.";
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "Gerai";
|
||||
@@ -119,14 +119,14 @@
|
||||
"a2_Friday" = "Pn";
|
||||
"a2_Saturday" = "Š";
|
||||
"Access Rights" = "Prieigos teisės";
|
||||
"Add User" = "Pridėti vartotoją";
|
||||
"Add User" = "Pridėti naudotoją";
|
||||
"Loading" = "Įkrovimas";
|
||||
"No such user." = "Tokio vartotojo nėra.";
|
||||
"No such user." = "Tokio naudotojo nėra.";
|
||||
"You cannot (un)subscribe to a folder that you own!" = "Jūs negalite (atsisakyti) užsiregistruoti šio aplanko, nes jis jums priklauso!";
|
||||
|
||||
/* SMIME Certificate field */
|
||||
"S/MIME Certificate" = "S/MIME Certificate";
|
||||
"Subject Name" = "Subject Name";
|
||||
"S/MIME Certificate" = "S/MIME Sertifikatas";
|
||||
"Subject Name" = "Temos pavadinimas";
|
||||
"Issuer" = "Issuer";
|
||||
"streetAddress" = "Street";
|
||||
"stateOrProvinceName" = "State or Province";
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"Reduce" = "Zmniejsz";
|
||||
|
||||
/* tooltip */
|
||||
"Refresh" = "Refresh";
|
||||
"Refresh" = "Odśwież";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
@@ -109,7 +109,7 @@
|
||||
"Personal" = "Osobiste";
|
||||
"To Do" = "Do zrobienia";
|
||||
"Later" = "Później";
|
||||
"Forwarded" = "Forwarded";
|
||||
"Forwarded" = "Przekazane";
|
||||
"Return Receipt Sent" = "Potwierdzenie wysłane";
|
||||
"a2_Sunday" = "Ni";
|
||||
"a2_Monday" = "Pn";
|
||||
@@ -227,9 +227,9 @@
|
||||
"Move forward" = "Idź naprzód";
|
||||
|
||||
/* Password Recovery */
|
||||
"passwordRecovery_Disabled" = "Disabled";
|
||||
"passwordRecovery_SecretQuestion" = "Secret question";
|
||||
"passwordRecovery_SecretQuestion1" = "What is the name of your first pet ?";
|
||||
"passwordRecovery_SecretQuestion2" = "What was your first car ?";
|
||||
"passwordRecovery_SecretQuestion3" = "What is your favorite movie ?";
|
||||
"passwordRecovery_SecondaryEmail" = "Secondary E-mail";
|
||||
"passwordRecovery_Disabled" = "Zablokowane";
|
||||
"passwordRecovery_SecretQuestion" = "Poufne pytanie";
|
||||
"passwordRecovery_SecretQuestion1" = "Jakie jest imię twojego pierwszego zwierzaka?";
|
||||
"passwordRecovery_SecretQuestion2" = "Jaki miałeś pierwszy samochód?";
|
||||
"passwordRecovery_SecretQuestion3" = "Jaki jest twój ulubiony film?";
|
||||
"passwordRecovery_SecondaryEmail" = "Dodatkowy e-mail";
|
||||
|
||||
@@ -101,7 +101,11 @@
|
||||
NSDictionary *currentUserInfos;
|
||||
NSMutableDictionary *userData;
|
||||
id <WOActionResults> result;
|
||||
WORequest *request;
|
||||
NSArray *reqPathArray;
|
||||
NSEnumerator *aclsEnum;
|
||||
BOOL defaultUserDisable;
|
||||
SOGoSystemDefaults *sd;
|
||||
|
||||
if (!prepared)
|
||||
{
|
||||
@@ -142,8 +146,27 @@
|
||||
}
|
||||
|
||||
// Add the 'Any authenticated' user
|
||||
if (defaultUserID)
|
||||
request = [[self context] request];
|
||||
reqPathArray = [request requestHandlerPathArray];
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingMail]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingMail]) {
|
||||
defaultUserDisable = YES;
|
||||
}
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingContacts]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingContacts]) {
|
||||
defaultUserDisable = YES;
|
||||
}
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingCalendar]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingCalendar]) {
|
||||
defaultUserDisable = YES;
|
||||
}
|
||||
if (!defaultUserDisable && defaultUserID)
|
||||
{
|
||||
|
||||
userData = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
defaultUserID, @"uid",
|
||||
[self labelForKey: @"Any Authenticated User"], @"cn",
|
||||
|
||||
@@ -292,6 +292,32 @@
|
||||
while ((currentUser = [usersList nextObject]))
|
||||
{
|
||||
currentUid = [currentUser objectForKey: @"uid"];
|
||||
|
||||
//Check if we disable the fact to set rights for defaultsUser
|
||||
if (!defaultUserID)
|
||||
ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
|
||||
if([currentUid isEqualToString: defaultUserID])
|
||||
{
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingMail]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingMail]) {
|
||||
response = [self responseWithStatus: 403];
|
||||
return response;
|
||||
}
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingContacts]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingContacts]) {
|
||||
response = [self responseWithStatus: 403];
|
||||
return response;
|
||||
}
|
||||
if (NSNotFound != [reqPathArray indexOfObject: kDisableSharingCalendar]
|
||||
&& nil != [sd disableSharingAnyAuthUser]
|
||||
&& NSNotFound != [[sd disableSharingAnyAuthUser] indexOfObject: kDisableSharingCalendar]) {
|
||||
response = [self responseWithStatus: 403];
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
if (!([self _initRightsForUserID: currentUid]))
|
||||
{
|
||||
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"No such user."]
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "العمل";
|
||||
"Mobile" = "Mobile";
|
||||
"Pager" = "النداء";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "الزميل، المنافس، العملاء، الصديق، العائلة، شريك تجاري، مقدم خدمة، الصحافة ، كبار الشخصيات";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Lana";
|
||||
"Mobile" = "Mugikorra";
|
||||
"Pager" = "Orrikatzailea";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Lankide, Lehiakide, Bezero, Lagun, Familia, Negoziokidea, Hornitzailea, Prentsa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Posao";
|
||||
"Mobile" = "Mobilni";
|
||||
"Pager" = "Pejdžer";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurent, Klijent, Prijatelj, Porodica, Poslovni Partner, Provajder, Štampa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Comercial";
|
||||
"Mobile" = "Celular";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Baixe perfil de configuração para iOS -MacOS ";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colega, Concorrente, Cliente, Amigo, Família, Parceiro de Negócios, Provedor, Press, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Работа";
|
||||
"Mobile" = "Мобилно";
|
||||
"Pager" = "Пейджър";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Колега, Конкурент, Клиент, Приятел, Член на семейството, Бизнес партньор, Доставчик, Преса, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Feina";
|
||||
"Mobile" = "Mòbil";
|
||||
"Pager" = "Cercapersones";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "工作";
|
||||
"Mobile" = "手机";
|
||||
"Pager" = "传呼";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "同事, 竞争对手, 客户, 朋友, 家庭, 工作伙伴, 供应商, 媒体, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "公司";
|
||||
"Mobile" = "手機";
|
||||
"Pager" = "呼叫器";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "同事,競爭對手,客戶,朋友,家人,事業夥伴,供應商,出版社,VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Posao";
|
||||
"Mobile" = "Mobitel";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Natjecatelj, Kupac, Prijatelj, Obitelj, Poslovni partner, Uslužitelj, Tisak, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Zaměstnání";
|
||||
"Mobile" = "Mobilní telefon";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurent, Zákazník, Přítel, Rodina, Obchodní partner, Dodavatel, Tisk, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Arbejde";
|
||||
"Mobile" = "Mobil";
|
||||
"Pager" = "Personsøger";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS-konfigurationsprofil";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "kollega, konkurrent, kunde, ven, familie, samarbejdspartner, udbyder, presse, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Werk";
|
||||
"Mobile" = "Mobiel";
|
||||
"Pager" = "Pieper";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Collega, Concurrent, Klant, Vriend, Familie, Zakenpartner, Leverancier, Pers, VIP";
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
"Work" = "Work";
|
||||
"Mobile" = "Mobile";
|
||||
"Pager" = "Pager";
|
||||
"Download configuration profile" = "Download configuration profile";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Työ";
|
||||
"Mobile" = "GSM";
|
||||
"Pager" = "Hakulaite";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kollega, Kilpailija, Asiakas, Ystävä, Perhe, Liikekummpani, Palveluntarjoaja, Lehdistö, VIP";
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
"Work" = "Travail";
|
||||
"Mobile" = "Portable";
|
||||
"Pager" = "Téléavertisseur";
|
||||
"Download configuration profile" = "Télécharger le profil de configuration";
|
||||
"Download iOS - MacOS configuration profile" = "Télécharger le profil de configuration pour iOS - MacOS";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Ami, Client, Collègue, Concurrent, Famille, Fournisseur, Partenaire d'affaire, Presse, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Traballo";
|
||||
"Mobile" = "Móbil";
|
||||
"Pager" = "Buscapersonas";
|
||||
"Download iOS - MacOS configuration profile" = "Descargar o perfil de configuración de iOS - MacOS";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colega, Competidor, Cliente, Amigo, Familia, Socio, Provedor, Prensa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Dienstlich";
|
||||
"Mobile" = "Handy";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "iOS - MacOS Konfigurationsprofil herunterladen";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Anbieter, Familienmitglied, Freund, Geschäftspartner, Kollegin, Konkurrent, Kunde, Lieferant, Presse, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "עבודה";
|
||||
"Mobile" = "נייד";
|
||||
"Pager" = "ביפר";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "עמית, מתחרה, לקוח, חבר, משפחה, שותף עסקי, ספק, עיתונות, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Munkahely";
|
||||
"Mobile" = "Mobiltelefon";
|
||||
"Pager" = "Személyhívó";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Munkatárs, Versenytárs, Felhasználó, Barát, Család, Üzleti partner, Szolgáltató, Sajtó, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Vinnusími";
|
||||
"Mobile" = "Farsími";
|
||||
"Pager" = "Símboði";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Samstarfsmaður, Keppinautur, Viðskiptavinur, Vinur, Fjölskylda, Viðskiptatengsl, Þjónustuaðili, Fjölmiðlar, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Kerja";
|
||||
"Mobile" = "Handphone";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Rekan, Pesaing, Pelanggan, Teman, Keluarga, Mitra Bisnis, Provider, Pers, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Lavoro";
|
||||
"Mobile" = "Cellulare";
|
||||
"Pager" = "Cerca Persone";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Collega, Concorrente, Cliente, Amico, Famiglia, Socio, Provider, Stampa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "職業";
|
||||
"Mobile" = "携帯電話";
|
||||
"Pager" = "ポケベル";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "同僚, 競合企業, 顧客, 友達, 家族, ビジネスパートナー, プロバイダー, 報道機関, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Жұмыс";
|
||||
"Mobile" = "Ұялы";
|
||||
"Pager" = "Пейджер";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Әріптес, Бәсекелес, Клиент, Дос, Отбасы, Серіктес, Жеткізуші, Баспасөз, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Darbs";
|
||||
"Mobile" = "Mobilais";
|
||||
"Pager" = "Peidžeris";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolēģi, konkurenti, klienti, draugi, ģimene, biznesa partneri, piegādātāji, Prese, VIP";
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
"Copy To" = "Kopijuoti į";
|
||||
"Add to" = "Pridėti prie";
|
||||
"To" = "To";
|
||||
"Carbon Copy (Cc)" = "Carbon Copy (Cc)";
|
||||
"Blind Carbon Copy (Bcc)" = "Blind Carbon Copy (Bcc)";
|
||||
"Carbon Copy (Cc)" = "Kopija (Cc)";
|
||||
"Blind Carbon Copy (Bcc)" = "Nematomoji kopija (Bcc)";
|
||||
|
||||
/* Search scope: name fields */
|
||||
"name" = "Vardas";
|
||||
@@ -58,7 +58,7 @@
|
||||
"mozillanickname" = "Antras el. paštas";
|
||||
|
||||
/* Search scope: screen name field */
|
||||
"nsaimid" = "Screen name";
|
||||
"nsaimid" = "Abonento vardas";
|
||||
|
||||
/* Search scope: mail fields */
|
||||
"mail" = "Mail";
|
||||
@@ -174,11 +174,11 @@
|
||||
"Sharing..." = "Bendrinti...";
|
||||
"Write" = "Rašyti";
|
||||
"Delete" = "Panaikinti";
|
||||
"Instant Message" = "Greitoji žinutė";
|
||||
"Instant Message" = "Žinutė";
|
||||
"Add..." = "Pridėti";
|
||||
"Remove" = "Pašalinti";
|
||||
"Please wait..." = "Prašome palaukti...";
|
||||
"No possible subscription" = "Nėra įmanomos prenumeratos";
|
||||
"No possible subscription" = "Prenumerata negalima";
|
||||
"Preferred" = "Pageidautina";
|
||||
"Display" = "Rodyti";
|
||||
"Display Name" = "Ekrano vardas";
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Darbo";
|
||||
"Mobile" = "Mobilus:";
|
||||
"Pager" = "Gaviklis:";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, konkurentas, Klientas, Draugas, Šeima, Verslo partneris, Teikėjas, Spauda, VIP";
|
||||
@@ -213,28 +214,28 @@
|
||||
"Timezone" = "Laiko juosta";
|
||||
"Birthday" = "Gimtadienis";
|
||||
"Birthday (yyyy-mm-dd)" = "Gimtadienis (yyyy-mm-dd):";
|
||||
"Freebusy URL" = "Laisvalaikiui ir užimto adresas";
|
||||
"Freebusy URL" = "Užimtumo adresas";
|
||||
"Add as..." = "Pridėti kaip...";
|
||||
"Recipient" = "Gavėjas";
|
||||
"Carbon Copy" = "Kopija";
|
||||
"Blind Carbon Copy" = "Nematoma kopija";
|
||||
"New Addressbook..." = "Nauja adresų knyga...";
|
||||
"Subscribe to an Addressbook..." = "Įsirašyti į adresų knygą...";
|
||||
"Remove the selected Addressbook" = "Ištrinti pažymętus iš adresų knygos";
|
||||
"Subscribe to a shared contact" = "Subscribe to a shared addressbook";
|
||||
"Search User" = "Ieškoti vartotojo";
|
||||
"Subscribe to an Addressbook..." = "Prenumeruoti adresų knygą...";
|
||||
"Remove the selected Addressbook" = "Pašalinti pasirinktą adresų knygą";
|
||||
"Subscribe to a shared contact" = "Prisijungti prie bendros adresų knygos";
|
||||
"Search User" = "Ieškoti naudotojo";
|
||||
"Name of the Address Book" = "Adresų knygos pavadinimas";
|
||||
"Are you sure you want to delete the selected address book?"
|
||||
= "Ar jūs įsitikinęs, jog norite ištrinti pažymėtą adresų knygą?";
|
||||
"Are you sure you want to delete the addressbook \"%{0}\"?"
|
||||
= "Ar tikrai norite ištrinti adresų knygelę \"%{0}\"?";
|
||||
= "Ar tikrai norite ištrinti adresų knygą \"%{0}\"?";
|
||||
"You cannot remove nor unsubscribe from a public addressbook."
|
||||
= "Jūs negalite pašalinti arba atsisakyti iš viešos adresų knygos.";
|
||||
"You cannot remove nor unsubscribe from your personal addressbook."
|
||||
= "Jūs negalite pašalinti arba atsisakyti iš jūsų asmeninės adresų knygos.";
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Ar tikrai norite ištrinti pasirinktus kontaktus?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "Are you sure you want to delete the card of %{0}?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "Ar tikrai norite ištrinti kortelę %{0}?";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "Jūs negalite trinti kortelės iš \"%{0}\".";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
@@ -243,15 +244,15 @@
|
||||
= "Nepavyko prisijungti prie šio aplanko.";
|
||||
|
||||
/* security */
|
||||
"Security" = "Security";
|
||||
"Security" = "Saugumas";
|
||||
"Uninstall" = "Uninstall";
|
||||
"Error reading the card certificate." = "Error reading the card certificate.";
|
||||
"No certificate associated to card." = "No certificate associated to card.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Prieigos teisės";
|
||||
"For user" = "Vartotojui";
|
||||
"Any Authenticated User" = "Visiems autorizuotiems vartotojams";
|
||||
"For user" = "Naudotojui";
|
||||
"Any Authenticated User" = "Visiems autorizuotiems naudotojams";
|
||||
"Public Access" = "Viešas priėjimas";
|
||||
"This person can add cards to this addressbook."
|
||||
= "Šis asmuo gali pridėti korteles šioje adresų knygoje.";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Работа";
|
||||
"Mobile" = "Мобилен";
|
||||
"Pager" = "Пејџер";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Колега, конкурент, клиент, пријател, фамилија, деловен партнер, провајдер, новинар, ВИП";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Posao";
|
||||
"Mobile" = "Mobilni";
|
||||
"Pager" = "Pejdžer";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurent, Klijent, Prijatelj, Porodica, Poslovni Partner, Provajder, Novinar, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Arbeid";
|
||||
"Mobile" = "Mobiltelefon";
|
||||
"Pager" = "Personsøker";
|
||||
"Download iOS - MacOS configuration profile" = "Last ned konfigurasjonsprofil for iOS - MacOS";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kollega, Konkurrent, Kunde, Venn, Familie, Forretningspartner, Leverandør, Presse, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Arbeid";
|
||||
"Mobile" = "Mobiltelefon";
|
||||
"Pager" = "Personsøker";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Praca";
|
||||
"Mobile" = "Telefon kom.";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Pobierz profil konfiguracyjny iOS - MacOS";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurencja, Klient, Przyjaciel, Rodzina, Biznes, Dostawca, Prasa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Trabalho";
|
||||
"Mobile" = "Móvel";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Descarregar perfil de configuração para iOS - MacOS";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colega, Concorrência, Cliente, Amigo, Família, Parceiro de Negócios, Fornecedor, Imprensa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Muncă";
|
||||
"Mobile" = "Mobil";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Coleg, Competitor, Client, Prieten, Familie, Partener de Business, Furnizor, Presă, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Рабочий";
|
||||
"Mobile" = "Мобильный";
|
||||
"Pager" = "Пейджер";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Коллега, Конкурент, Клиент, Друг, Семья, Партнер, Поставщик, Пресса, VIP";
|
||||
@@ -340,7 +341,7 @@
|
||||
"Import" = "Импорт";
|
||||
"More options" = "Больше опций";
|
||||
"Role" = "Роль";
|
||||
"Add Screen Name" = "Добавить имя экрана";
|
||||
"Add Screen Name" = "Добавить отображаемое имя";
|
||||
"Custom 1" = "Настраиваемое 1";
|
||||
"Custom 2" = "Настраиваемое 2";
|
||||
"Custom 3" = "Настраиваемое 3";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Посао";
|
||||
"Mobile" = "Мобилни";
|
||||
"Pager" = "Пејџер";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Колега, Конкурент, Клијент, Пријатељ, Породица, Пословни Партнер, Провајдер, Новинар, ВИП";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Posao";
|
||||
"Mobile" = "Mobilni";
|
||||
"Pager" = "Pejdžer";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurent, Klijent, Prijatelj, Porodica, Poslovni Partner, Provajder, Novinar, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Do práce";
|
||||
"Mobile" = "Mobil";
|
||||
"Pager" = "Pager";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Konkurent, Zákazník, Priateľ, Rodina, Obchodný partner, Dodávateľ, Novinár, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Služba";
|
||||
"Mobile" = "Mobilni telefon";
|
||||
"Pager" = "Pozivnik";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kolega, Tekmec, Stranka, Prijatelj, Družina, Poslovni partner, Dobavitelj, Novinar, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Trabajo";
|
||||
"Mobile" = "Celular";
|
||||
"Pager" = "Buscapersonas";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colega, Competidor, Cliente, Amigo, Familia, Socio, Proveedor, Prensa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Trabajo";
|
||||
"Mobile" = "Móvil";
|
||||
"Pager" = "Busca";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colega, Competidor, Cliente, Amigo, Familia, Socio, Proveedor, Prensa, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Arbete";
|
||||
"Mobile" = "Mobiltelefon";
|
||||
"Pager" = "Personsökare";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Kollega, Konkurrent, Kund, Vän, Familj, Affärspartner, Leverantör, Press, VIP";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "İş";
|
||||
"Mobile" = "Cep";
|
||||
"Pager" = "Çağrı cihazı";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Meslektaş, Rakip, Müşteri, Arkadaş, Aile, İş Ortağı, Tedarikçi, Basın, VIP";
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
@@ -78,35 +80,47 @@ static NSArray *photoTags = nil;
|
||||
id currentChild;
|
||||
SOGoContactGCSFolder *sourceFolder;
|
||||
NSMutableString *content;
|
||||
SOGoSystemDefaults *sd;
|
||||
|
||||
content = [NSMutableString string];
|
||||
sourceFolder = [self clientObject];
|
||||
contactsId = [[[[context request] contentAsString] objectFromJSONString] objectForKey: @"uids"];
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
if (nil != [sd disableExport] && NSNotFound != [[sd disableExport] indexOfObject: kDisableSharingContacts])
|
||||
{
|
||||
response = [self responseWithStatus: 401
|
||||
andJSONRepresentation: [NSDictionary dictionaryWithObject: @"Exporting contacts folder is not authorized"
|
||||
forKey: @"message"]];
|
||||
|
||||
if (!contactsId)
|
||||
contactsId = [sourceFolder toOneRelationshipKeys];
|
||||
}
|
||||
else
|
||||
{
|
||||
content = [NSMutableString string];
|
||||
sourceFolder = [self clientObject];
|
||||
contactsId = [[[[context request] contentAsString] objectFromJSONString] objectForKey: @"uids"];
|
||||
|
||||
uids = [contactsId objectEnumerator];
|
||||
while ((uid = [uids nextObject]))
|
||||
{
|
||||
currentChild = [sourceFolder lookupName: uid
|
||||
inContext: [self context]
|
||||
acquire: NO];
|
||||
if ([currentChild respondsToSelector: @selector (vCard)])
|
||||
[content appendFormat: @"%@", [[currentChild ldifRecord] ldifRecordAsString]];
|
||||
else if ([currentChild respondsToSelector: @selector (vList)])
|
||||
[content appendFormat: @"%@", [[currentChild vList] ldifString]];
|
||||
[content appendString: @"\n"];
|
||||
}
|
||||
if (!contactsId)
|
||||
contactsId = [sourceFolder toOneRelationshipKeys];
|
||||
|
||||
response = [context response];
|
||||
[response setHeader: @"application/directory; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
filename = [NSString stringWithFormat: @"%@.ldif",
|
||||
[[sourceFolder displayName] asQPSubjectString: @"utf-8"]];
|
||||
disposition = [NSString stringWithFormat: @"attachment; filename=\"%@\"", filename];
|
||||
[response setHeader: disposition forKey: @"Content-Disposition"];
|
||||
[response setContent: [content dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
uids = [contactsId objectEnumerator];
|
||||
while ((uid = [uids nextObject]))
|
||||
{
|
||||
currentChild = [sourceFolder lookupName: uid
|
||||
inContext: [self context]
|
||||
acquire: NO];
|
||||
if ([currentChild respondsToSelector: @selector (vCard)])
|
||||
[content appendFormat: @"%@", [[currentChild ldifRecord] ldifRecordAsString]];
|
||||
else if ([currentChild respondsToSelector: @selector (vList)])
|
||||
[content appendFormat: @"%@", [[currentChild vList] ldifString]];
|
||||
[content appendString: @"\n"];
|
||||
}
|
||||
|
||||
response = [context response];
|
||||
[response setHeader: @"application/directory; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
filename = [NSString stringWithFormat: @"%@.ldif",
|
||||
[[sourceFolder displayName] asQPSubjectString: @"utf-8"]];
|
||||
disposition = [NSString stringWithFormat: @"attachment; filename=\"%@\"", filename];
|
||||
[response setHeader: disposition forKey: @"Content-Disposition"];
|
||||
[response setContent: [content dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -507,6 +507,20 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL) isContactExportEnabled {
|
||||
BOOL result;
|
||||
SOGoSystemDefaults *sd;
|
||||
|
||||
result = YES;
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
if (nil != [sd disableExport]
|
||||
&& NSNotFound != [[sd disableExport] indexOfObject: kDisableSharingContacts]) {
|
||||
result = NO;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (id) defaultAction
|
||||
{
|
||||
// NSString *check;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#import <SoObjects/Contacts/SOGoContactGCSEntry.h>
|
||||
#import <SoObjects/Contacts/SOGoContactGCSFolder.h>
|
||||
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
|
||||
|
||||
#import "UIxContactsListActions.h"
|
||||
|
||||
@@ -138,19 +139,20 @@
|
||||
|
||||
- (NSArray *) contactInfos
|
||||
{
|
||||
id <SOGoContactFolder> folder;
|
||||
id <SOGoContactFolder> folder, sourceFolder;
|
||||
NSString *ascending, *valueText;
|
||||
NSArray *results, *searchFields, *fields;
|
||||
NSMutableArray *filteredContacts, *headers;
|
||||
NSArray *searchFields, *fields, *folders, *tmpGlobalAddressBookResults;
|
||||
NSMutableArray *filteredContacts, *headers, *results, *globalAddressBookResults;
|
||||
NSDictionary *data, *contact;
|
||||
BOOL excludeLists;
|
||||
NSComparisonResult ordering;
|
||||
NSUInteger max, count;
|
||||
unsigned int i;
|
||||
NSSortDescriptor *descriptor;
|
||||
NSMutableDictionary *tmpDict;
|
||||
|
||||
if (!contactInfos)
|
||||
{
|
||||
folder = [self clientObject];
|
||||
data = [self requestData];
|
||||
|
||||
ascending = [data objectForKey: @"asc"];
|
||||
@@ -167,11 +169,80 @@
|
||||
excludeLists = [[data objectForKey: @"excludeLists"] boolValue];
|
||||
|
||||
[contactInfos release];
|
||||
results = [folder lookupContactsWithFilter: valueText
|
||||
|
||||
sourceFolder = [self clientObject];
|
||||
globalAddressBookResults = nil;
|
||||
if (![sourceFolder isKindOfClass: [SOGoContactSourceFolder class]]) {
|
||||
folders = [[[self clientObject] container] subFolders];
|
||||
|
||||
for (folder in folders) {
|
||||
// Global AB
|
||||
if ([folder isKindOfClass: [SOGoContactSourceFolder class]] && (![folder isEqual: [self clientObject]])) {
|
||||
tmpGlobalAddressBookResults = [folder lookupContactsWithFilter: valueText
|
||||
onCriteria: nil
|
||||
sortBy: [self sortKey]
|
||||
ordering: ordering
|
||||
inDomain: [[context activeUser] domain]];
|
||||
if (globalAddressBookResults) {
|
||||
globalAddressBookResults = [NSMutableArray arrayWithArray: [globalAddressBookResults arrayByAddingObjectsFromArray: tmpGlobalAddressBookResults]];
|
||||
} else {
|
||||
globalAddressBookResults = [NSMutableArray arrayWithArray: tmpGlobalAddressBookResults];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process for global address book instead of array
|
||||
if (globalAddressBookResults) {
|
||||
for (i = 0 ; i < [globalAddressBookResults count] ; i++) {
|
||||
tmpDict = [NSMutableDictionary dictionaryWithDictionary: [globalAddressBookResults objectAtIndex: i]];
|
||||
// Flatten emails
|
||||
if ([tmpDict objectForKey: @"c_mail"] && [[tmpDict objectForKey: @"c_mail"] isKindOfClass:[NSArray class]] && [[tmpDict objectForKey: @"c_mail"] count] > 0) {
|
||||
[tmpDict setObject:[[tmpDict objectForKey: @"c_mail"] componentsJoinedByString: @","] forKey:@"c_mail"];
|
||||
}
|
||||
|
||||
if ((![tmpDict objectForKey:@"c_cn"] || [tmpDict objectForKey:@"c_cn"] == [NSNull null]) && [tmpDict objectForKey:@"c_name"]) {
|
||||
// Replace c_cn if not filled
|
||||
[tmpDict setObject:[tmpDict objectForKey:@"c_name"] forKey:@"c_cn"];
|
||||
}
|
||||
|
||||
if ((![tmpDict objectForKey:@"c_uid"] || [tmpDict objectForKey:@"c_uid"] == [NSNull null]) && [tmpDict objectForKey:@"c_id"]) {
|
||||
// Replace c_uid if not filled
|
||||
[tmpDict setObject:[tmpDict objectForKey:@"c_uid"] forKey:@"c_id"];
|
||||
}
|
||||
|
||||
[globalAddressBookResults replaceObjectAtIndex:i withObject: tmpDict];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Current AB
|
||||
results = [NSMutableArray arrayWithArray: [sourceFolder lookupContactsWithFilter: valueText
|
||||
onCriteria: searchFields
|
||||
sortBy: [self sortKey]
|
||||
ordering: ordering
|
||||
inDomain: [[context activeUser] domain]];
|
||||
inDomain: [[context activeUser] domain]]];
|
||||
|
||||
// Add sourceid for current AB
|
||||
for (i = 0 ; i < [results count] ; i++) {
|
||||
tmpDict = [NSMutableDictionary dictionaryWithDictionary: [results objectAtIndex: i]];
|
||||
// Add sourceid
|
||||
[tmpDict setObject:[sourceFolder nameInContainer] forKey:@"sourceid"];
|
||||
[results replaceObjectAtIndex:i withObject: tmpDict];
|
||||
}
|
||||
|
||||
if (globalAddressBookResults && results) { // Both results, merge arrays
|
||||
// Results in personal folder will appear first
|
||||
results = [results arrayByAddingObjectsFromArray: globalAddressBookResults];
|
||||
} else if (globalAddressBookResults) { // No results in personal AB
|
||||
results = globalAddressBookResults;
|
||||
}
|
||||
|
||||
// Sort the results
|
||||
descriptor = [[NSSortDescriptor alloc] initWithKey: [self sortKey]
|
||||
ascending: ordering];
|
||||
results = [results sortedArrayUsingDescriptors: [NSArray arrayWithObjects: descriptor, nil]];
|
||||
[descriptor release];
|
||||
|
||||
if (excludeLists)
|
||||
{
|
||||
filteredContacts = [NSMutableArray array];
|
||||
@@ -198,6 +269,7 @@
|
||||
count = 0;
|
||||
fields = [[contactInfos objectAtIndex: 0] allKeys];
|
||||
[headers addObject: fields];
|
||||
|
||||
while (count < max)
|
||||
{
|
||||
[headers addObject: [[contactInfos objectAtIndex: count] objectsForKeys: fields
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
|
||||
|
||||
#import <Contacts/SOGoContactGCSEntry.h>
|
||||
#import <Contacts/SOGoContactGCSFolder.h>
|
||||
|
||||
@@ -173,12 +175,14 @@
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NSDictionary *values;
|
||||
NSArray *initialReferences, *refs, *emails;
|
||||
NSArray *initialReferences, *refs, *emails, *folders;
|
||||
NSDictionary *currentReference;
|
||||
NSString *uid, *workMail, *fn, *newUID;
|
||||
int i, count;
|
||||
NGVCardReference *cardReference;
|
||||
SOGoContactGCSFolder *folder;
|
||||
NSMutableArray *publicSourceIDs;
|
||||
id f;
|
||||
|
||||
folder = [co container];
|
||||
|
||||
@@ -200,12 +204,25 @@
|
||||
count = [references count];
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// List container name of global AB
|
||||
folders = [[[co lookupUserFolder] privateContacts: @"Contacts" inContext: nil] subFolders];
|
||||
publicSourceIDs = [[NSMutableArray alloc] init];
|
||||
for (f in folders) {
|
||||
if ([f isKindOfClass:[SOGoContactSourceFolder class]]) {
|
||||
[publicSourceIDs addObject: [f nameInContainer]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if ([[references objectAtIndex: i] isKindOfClass: [NSDictionary class]])
|
||||
{
|
||||
currentReference = [references objectAtIndex: i];
|
||||
|
||||
uid = [currentReference objectForKey: @"id"];
|
||||
|
||||
|
||||
if (![self cardReferences: [list cardReferences]
|
||||
contain: uid])
|
||||
{
|
||||
@@ -222,8 +239,18 @@
|
||||
|
||||
[list addCardReference: cardReference];
|
||||
}
|
||||
else
|
||||
{
|
||||
else if ([currentReference objectForKey:@"sourceid"] && [publicSourceIDs containsObject:[currentReference objectForKey:@"sourceid"]]) {
|
||||
// Create reference for shared AB (public)
|
||||
uid = [currentReference objectForKey: @"id"];
|
||||
emails = [[currentReference objectForKey: @"c_mail"] componentsSeparatedByString: @","];
|
||||
cardReference = [NGVCardReference elementWithTag: @"card"];
|
||||
[cardReference setFn: [currentReference objectForKey: @"c_cn"]];
|
||||
if ([emails count])
|
||||
[cardReference setEmail: [emails objectAtIndex: 0]];
|
||||
[cardReference setReference: uid];
|
||||
|
||||
[list addCardReference: cardReference];
|
||||
} else {
|
||||
// Invalid UID or no UID
|
||||
NGVCard *newCard;
|
||||
CardElement *newWorkMail;
|
||||
@@ -264,6 +291,8 @@
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
[publicSourceIDs release];
|
||||
}
|
||||
|
||||
- (BOOL) cardReferences: (NSArray *) references
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
|
||||
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
|
||||
|
||||
#import "UIxListView.h"
|
||||
|
||||
@implementation UIxListView
|
||||
@@ -36,6 +38,7 @@
|
||||
NGVCardReference *card, *cardCopy;
|
||||
int i, count;
|
||||
id test;
|
||||
NSArray *folders;
|
||||
|
||||
invalid = [NSMutableArray array];
|
||||
|
||||
@@ -46,7 +49,22 @@
|
||||
test = [[co container] lookupName: [card reference]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
if ([test isKindOfClass: [NSException class]])
|
||||
if ([test isKindOfClass: [NSException class]]) {
|
||||
folders = [[[co lookupUserFolder] privateContacts: @"Contacts" inContext: nil] subFolders];
|
||||
id <SOGoContactFolder> folder;
|
||||
for (folder in folders) {
|
||||
// Global AB
|
||||
if ([folder isKindOfClass: [SOGoContactSourceFolder class]]) {
|
||||
test = [folder lookupName: [card reference]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
if (test && ![test isKindOfClass: [NSException class]]) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (test && [test isKindOfClass: [NSException class]])
|
||||
{
|
||||
//NSLog (@"%@ not found", [card reference]);
|
||||
cardCopy = [card copy];
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Робочий";
|
||||
"Mobile" = "Мобільний";
|
||||
"Pager" = "Пейджер";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Робота, Конкуренти, Клієнти, Друзі, Родина, Партнери, Постачальники, Преса, ВІП";
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Work" = "Gwaith";
|
||||
"Mobile" = "Symudol";
|
||||
"Pager" = "Peiriant galw";
|
||||
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Cydweithiwr, Cystadleuydd, Cwsmer, Ffrind, Teulu, Partner Busnes, Darparwr, Y Wasg, Pwysigyn";
|
||||
|
||||
@@ -8,9 +8,9 @@ TENTATIVE = "preliminarus";
|
||||
organized_by_you = "jūsų organizuojama";
|
||||
you_are_an_attendee = "esate dalyvis";
|
||||
add_info_text = "iMIP 'Pridėti' prašymus dar nepalaiko SOGo.";
|
||||
publish_info_text = "Siuntėjas turi pranešti jums apie pridedamą įvykį.";
|
||||
publish_info_text = "Siuntėjas turi pranešti jums apie pridėtą įvykį.";
|
||||
cancel_info_text = "Jūsų kvietimas ar visas renginys buvo atšauktas.";
|
||||
request_info_no_attendee = "siūlo susitikimą dalyviams. Jūs gaunate šį laišką kaip pranešimą, bet Jūs nesate dalyvis.";
|
||||
request_info_no_attendee = "siūlo susitikimą dalyviams. Šį laišką gaunate kaip pranešimą, bet Jūs nesate dalyvis.";
|
||||
Appointment = "Paskyrimas";
|
||||
"Status Update" = "Būsenos atnaujinimas";
|
||||
was = "buvo";
|
||||
@@ -18,7 +18,7 @@ was = "buvo";
|
||||
Organizer = "Organizatorius";
|
||||
Time = "Laikas";
|
||||
Attendees = "Dalyviai";
|
||||
request_info = "kviečia jus dalyvauti posėdyje.";
|
||||
request_info = "kviečia dalyvauti susitikime.";
|
||||
"Add to calendar" = "Pridėti į kalendorių";
|
||||
"Delete from calendar" = "Ištrinti iš kalendoriaus";
|
||||
"Update status" = "Atnaujinti būseną";
|
||||
@@ -32,7 +32,7 @@ Tentative = "Preliminarus";
|
||||
reply_info_no_attendee = "Jūs gavote atsakymą pagal suplanuotą įvykį, bet siuntėjas nėra įvykio dalyvis";
|
||||
reply_info = "Šis atsakymas į susitikimo kvietimą yra jūsų baigtas.";
|
||||
"to" = "į";
|
||||
"Untitled" = "Neaiškus";
|
||||
"Untitled" = "Be pavadinimo";
|
||||
"Size" = "Dydis";
|
||||
"Subject" = "Tema";
|
||||
"From" = "Nuo";
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#import <NGMime/NGMimeBodyPart.h>
|
||||
#import <NGMime/NGMimeMultipartBody.h>
|
||||
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
|
||||
#import <UI/MailerUI/WOContext+UIxMailer.h>
|
||||
|
||||
#import "UIxMailRenderingContext.h"
|
||||
@@ -98,6 +100,7 @@
|
||||
NSString *contentType;
|
||||
id viewer, info;
|
||||
NSArray *parts;
|
||||
SOGoUserDefaults *ud;
|
||||
|
||||
NSUInteger i, max;
|
||||
|
||||
@@ -119,14 +122,23 @@
|
||||
[self setChildInfo: [parts objectAtIndex: i]];
|
||||
|
||||
info = [self childInfo];
|
||||
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||
[viewer setBodyInfo: info];
|
||||
[viewer setPartPath: [self childPartPath]];
|
||||
if ([self decodedFlatContent])
|
||||
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
||||
[viewer setAttachmentIds: attachmentIds];
|
||||
|
||||
ud = [[[self context] activeUser] userDefaults];
|
||||
|
||||
[renderedParts addObject: [viewer renderedPart]];
|
||||
if (!([info objectForKey:@"disposition"]
|
||||
&& [[info objectForKey:@"disposition"] objectForKey:@"type"]
|
||||
&& [[[[info objectForKey:@"disposition"] objectForKey:@"type"] uppercaseString] isEqualToString:@"INLINE"]
|
||||
&& [ud hideInlineAttachments])) {
|
||||
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||
[viewer setBodyInfo: info];
|
||||
[viewer setPartPath: [self childPartPath]];
|
||||
if ([self decodedFlatContent])
|
||||
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
||||
[viewer setAttachmentIds: attachmentIds];
|
||||
|
||||
|
||||
[renderedParts addObject: [viewer renderedPart]];
|
||||
}
|
||||
}
|
||||
|
||||
contentType = [NSString stringWithFormat: @"%@/%@",
|
||||
|
||||
@@ -319,7 +319,6 @@
|
||||
"Thread As Read" = "الموضوع مقروء";
|
||||
"As Read By Date..." = "كما يقرأ من التاريخ";
|
||||
"All Read" = "الكل مقروء";
|
||||
"Flag" = "علم";
|
||||
"As Junk" = "غير هام";
|
||||
"As Not Junk" = "ليس غير هام";
|
||||
"Run Junk Mail Controls" = "تشغيل عناصر تحكم البريد غير المرغوب فيه";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user