Compare commits

...
85 Commits
Author SHA1 Message Date
Hivert Quentin 55c477b193 fixbis 2025-11-27 16:42:25 +01:00
Hivert Quentin 7513f76be7 fix create folder that already exist 2025-11-27 16:14:47 +01:00
Hivert Quentin 78c6aa5236 test2 2025-11-27 15:27:36 +01:00
Hivert Quentin 1f48a7c95e test 2025-11-27 13:22:56 +01:00
Hivert Quentin 16ab99e7cf fix(vulnerability): prevent sogo to execute scripts pass in theme query 2025-11-26 13:22:38 +01:00
Hivert Quentin bd0547fb73 chore(js/css): update generated files 2025-11-25 01:00:34 -05:00
Hivert Quentin 03fa91dc22 fix(mail): use the correct replyTo when set to a non*default identity 2025-11-24 15:44:21 +01:00
Hivert Quentin e2b8494a9c fix(trad): typo in a transation key 2025-10-16 17:03:30 +02:00
Hivert Quentin d69f55c265 fix(tool): ranem-user properly change data in c_defaults and c_settings 2025-10-16 11:32:39 +02:00
Hivert Quentin f8638a3f4e fix(db): increase some column size 2025-10-15 17:07:37 +02:00
Hivert Quentin f18e3a05c3 chore(realease): 5.12.4 2025-10-06 09:52:02 +02:00
Hivert Quentin 6425a62e1a i18n(cy): Update Welsh translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 5021376daf i18n(uk): Update Ukrainian translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 8c38c9ce03 i18n(tr_TR): Update TurkishTurkey translations 2025-10-06 09:47:41 +02:00
Hivert Quentin f86a32d0a1 i18n(th): Update Thai translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 2ebb63767e i18n(sv): Update Swedish translations 2025-10-06 09:47:41 +02:00
Hivert Quentin c755ab3b4e i18n(es_ES): Update SpanishSpain translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 07e9d34865 i18n(es_AR): Update SpanishArgentina translations 2025-10-06 09:47:40 +02:00
Hivert Quentin 645be8fcc5 i18n(sl_SI): Update Slovenian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin 0f24c17516 i18n(sk): Update Slovak translations 2025-10-06 09:47:39 +02:00
Hivert Quentin c675dbfaa7 i18n(sr@latin): Update SerbianLatin translations 2025-10-06 09:47:39 +02:00
Hivert Quentin dd367b0e94 i18n(sr): Update Serbian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin 1a80fd6284 i18n(ru): Update Russian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin ec4d7807d9 i18n(ro_RO): Update Romanian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 972ffcc0c6 i18n(pt): Update Portuguese translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 3a442f1b3d i18n(nn_NO): Update NorwegianNynorsk translations 2025-10-06 09:47:38 +02:00
Hivert Quentin eab6d9f249 i18n(nb_NO): Update NorwegianBokmal translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 3dc9b90992 i18n(sr_ME@latin): Update Montenegrin translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 798bed54e2 i18n(mk_MK): Update Macedonian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 2b455fe587 i18n(lt): Update Lithuanian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ad7dc8f45e i18n(lv): Update Latvian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ed9121175a i18n(ko): Update Korean translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 6514fbb8f1 i18n(kk): Update Kazakh translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 9a295c5944 i18n(ja): Update Japanese translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 1bb74c7522 i18n(it): Update Italian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 56e4929ca7 i18n(id_ID): Update Indonesian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 401e2f51cd i18n(is): Update Icelandic translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 799e8c21af i18n(hu): Update Hungarian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 070705acfa i18n(he): Update Hebrew translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 95e19379f6 i18n(de): Update German translations 2025-10-06 09:47:38 +02:00
Hivert Quentin f017fef4b2 i18n(gl): Update Galician translations 2025-10-06 09:47:38 +02:00
Hivert Quentin a914fd4151 i18n(fr): Update French translations 2025-10-06 09:47:38 +02:00
Hivert Quentin c0c506f910 i18n(fi): Update Finnish translations 2025-10-06 09:47:38 +02:00
Hivert Quentin b42882b564 i18n(nl): Update Dutch translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ae293ec3ce i18n(da_DK): Update Danish translations 2025-10-06 09:47:38 +02:00
Hivert Quentin e662f10389 i18n(hr_HR): Update Croatian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin c7a519ca12 i18n(zh_TW): Update ChineseTaiwan translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 22ab0b3c75 i18n(zh_CN): Update ChineseChina translations 2025-10-06 09:47:37 +02:00
Hivert Quentin b77129e2e7 i18n(ca): Update Catalan translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 4585293d99 i18n(bg_BG): Update Bulgarian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 9d277c3f15 i18n(pt_BR): Update BrazilianPortuguese translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 4461122697 i18n(bs_BA): Update Bosnian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin b96e531f66 i18n(eu): Update Basque translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 6c3e66142f i18n(ar): Update Arabic translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 16fcb46c4b i18n(pl): Update Polish translations 2025-10-06 09:47:37 +02:00
Hivert Quentin f252e0e2c2 i18n(cs): Update Czech translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 09d87b2d23 chore(UI): update theme-default 2025-10-06 09:33:17 +02:00
Hivert Quentin 9e20190fad fix(login): Only remember the login if the auth was successful 2025-10-02 13:37:56 +02:00
Hivert Quentin 981748754a fix(mailer): don't add mailto: to string starting with @ 2025-09-24 09:18:08 +02:00
Hivert Quentin 8d8ef5fd67 chore(js/css): update generated files 2025-09-23 01:00:35 -04:00
Hivert Quentin 666c979eea fix(mailer): correctly show interline for p element 2025-09-22 09:57:12 +02:00
Hivert Quentin 1d59c616ac chore(js/css): update generated files 2025-09-20 01:00:35 -04:00
Hivert Quentin a7f7950d91 fix(eas): use proper imap mech for EAS request when using openid 2025-09-19 16:47:16 +02:00
Hivert Quentin 5d616600df feat(mail): Add a setting to show the attachments above the mail body 2025-09-19 15:30:45 +02:00
Hivert Quentin a077512e34 fix(ui): add css class for login page 2025-09-19 09:50:15 +02:00
Hivert Quentin 23c8648169 fix(label): missing trad 2025-09-17 13:48:39 +02:00
Hivert Quentin 9fad7e6f9c chore(packaging): prepare debian 13 2025-09-16 16:11:23 +02:00
Hivert Quentin 0fb3db0608 fix(label): ensure the translation kept is not null 2025-09-16 16:09:01 +02:00
Hivert Quentin a7651e56c5 fix(task): fix reminder for tasks 2025-09-15 17:21:47 +02:00
Emily Kooistra 481a9bf1de perf(calendar): don't allocate and copy all children for each time we call _filterComponent:
Improving the filtering of the calender objects, keeping a global static of the array of tags
that are allowed. And using removeChildren to prevent the need of a full copy while we iterate
over it.
2025-09-15 15:43:05 +02:00
Emily Kooistra f48f27c812 perf(core): store translations in a globally static NSMutableDictionary
fetching public ICS files without this patch result in continual opening
and closing of the "Localizable.strings" to create a NSDictionary,
looking up one key and closing it again. By caching it in a static
variable this greatly improves the performance.
2025-09-15 15:43:05 +02:00
Hivert Quentin 86d94ab8fe fix(log): remove the ics from the log line 2025-08-27 10:19:42 +02:00
Hivert Quentin aba41a06b4 chore(js/css): update generated files 2025-08-21 01:00:36 -04:00
Hivert Quentin ed7a136e0f fix(password): Correctly check the secret question answer when hitting enter instead of the button next 2025-08-20 14:04:31 +02:00
Patrick Ben Koetter d99f020f82 chore(doc): Modernized Headings for easier editing (#370) 2025-08-08 10:45:12 +02:00
Hivert Quentin 244d1388eb fix(calendar): fetch our own iana timezone instead of trusting VTIMEZONE 2025-08-01 11:56:06 +02:00
Hivert Quentin dfcbbba514 chore(build): remove unnecessary import 2025-07-29 13:50:52 +02:00
Hivert Quentin 7bee193413 fix(mail): preoperly generates the message-id header value 2025-07-28 17:40:14 +02:00
Hivert Quentin 4ef79e219c fix(openid): correcly type userTokenInterval 2025-07-28 16:08:17 +02:00
Hivert Quentin 736d7589b1 fix(ldap): fetch the correct user source when creating an event with an attendee 2025-07-28 13:52:15 +02:00
Hivert Quentin 4d8cca10f6 fix(kdap): don't try to fetch for a nobody user 2025-07-28 13:28:30 +02:00
Hivert Quentin c8dd5535b3 fix(sieveà: Sieve use the correct imap auth mechanism 2025-07-24 15:03:30 +02:00
Hivert Quentin 42f620e562 fix(curl): properly close curl connection 2025-07-24 14:46:45 +02:00
Hivert Quentin 3662846900 chore(js/css): update generated files 2025-07-22 01:00:32 -04:00
Hivert Quentin b9f6b90740 Revert "fix(view): automatically refresh view only if a number is set."
This reverts commit 55dbae6bee.
2025-07-21 13:11:30 +02:00
164 changed files with 832 additions and 412 deletions

No files matched your search

+10 -3
View File
@@ -370,7 +370,9 @@ void handle_eas_terminate(int signum)
NSMutableString *s;
NSData *d;
int type;
int type, status;
status = 1;
parentId = [[(id)[theDocumentElement getElementsByTagName: @"ParentId"] lastObject] textValue];
displayName = [[(id)[theDocumentElement getElementsByTagName: @"DisplayName"] lastObject] textValue];
@@ -413,7 +415,12 @@ void handle_eas_terminate(int signum)
// FIXME
// handle exists (status == 2)
// handle right synckey
if ([newFolder create])
if([newFolder exists])
{
nameInContainer = [newFolder nameInContainer];
status = 2;
}
else if ([newFolder create])
{
SOGoMailAccount *accountFolder;
NSDictionary *imapGUIDs;
@@ -528,7 +535,7 @@ void handle_eas_terminate(int signum)
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<FolderCreate xmlns=\"FolderHierarchy:\">"];
[s appendFormat: @"<Status>%d</Status>", 1];
[s appendFormat: @"<Status>%d</Status>", status];
[s appendFormat: @"<SyncKey>%@</SyncKey>", syncKey];
[s appendFormat: @"<ServerId>%@</ServerId>", [nameInContainer stringByEscapingURL]];
[s appendString: @"</FolderCreate>"];
+1 -1
View File
@@ -1627,7 +1627,7 @@ struct GlobalObjectId {
[map setObject: dateReceived forKey: @"date"];
messageId = [NSString generateMessageID];
messageId = [NSString generateMessageID: [identity objectForKey: @"email"]];
[map setObject: messageId forKey: @"message-id"];
attachmentKeys = [self fetchFileAttachmentKeys];
+76
View File
@@ -2,6 +2,82 @@
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.12.4](https://github.com/Alinto/sogo/compare/SOGo-5.12.3...SOGo-5.13.0) (2025-10-06)
### Enhancements
* **mail:** Add a setting to show the attachments above the mail body ([5d61660](https://github.com/Alinto/sogo/commit/5d616600dfa6258e4eebcb5c065e393ebfae8f3a))
### Bug Fixes
* **calendar:** fetch our own iana timezone instead of trusting VTIMEZONE ([244d138](https://github.com/Alinto/sogo/commit/244d1388eb00c060c5302e5bfd997fd397820bc0))
* **curl:** properly close curl connection ([42f620e](https://github.com/Alinto/sogo/commit/42f620e56201e17391532507c02ae370f117c574))
* **eas:** use proper imap mech for EAS request when using openid ([a7f7950](https://github.com/Alinto/sogo/commit/a7f7950d91c83acd75c0b0d55dec74ab85d38d6c))
* **ldap:** don't try to fetch for a nobody user ([4d8cca1](https://github.com/Alinto/sogo/commit/4d8cca10f63aff9499b71d61d59d6f81570eb659))
* **label:** ensure the translation kept is not null ([0fb3db0](https://github.com/Alinto/sogo/commit/0fb3db060871a14e2abd8c6963ccd812cbacf200))
* **label:** missing trad ([23c8648](https://github.com/Alinto/sogo/commit/23c8648169b4893aaafa2e369259d94d56c76831))
* **ldap:** fetch the correct user source when creating an event with an attendee ([736d758](https://github.com/Alinto/sogo/commit/736d7589b16be4ebcf9fc6931a79187888c3b444))
* **login:** Only remember the login if the auth was successful ([9e20190](https://github.com/Alinto/sogo/commit/9e20190fad1a437f7e1307f0adcfe19a8d45184c))
* **log:** remove the ics from the log line ([86d94ab](https://github.com/Alinto/sogo/commit/86d94ab8fefaf3aa5ba99e13c28a0b24036d94ff))
* **mailer:** correctly show interline for p element ([666c979](https://github.com/Alinto/sogo/commit/666c979eeae6d51a6bc09684ebbab57ed9ce4b91))
* **mailer:** don't add mailto: to string starting with @ ([9817487](https://github.com/Alinto/sogo/commit/981748754a4857bab66a6fb94cdc5da4265ce003))
* **mail:** preoperly generates the message-id header value ([7bee193](https://github.com/Alinto/sogo/commit/7bee193413935ca03e4936a15791fbbb534493ec))
* **openid:** correcly type userTokenInterval ([4ef79e2](https://github.com/Alinto/sogo/commit/4ef79e219c289697eec0c2d100c8af1a5d0889b6))
* **password:** Correctly check the secret question answer when hitting enter instead of the button next ([ed7a136](https://github.com/Alinto/sogo/commit/ed7a136e0f2c5ecd35033aef6d0561d9fcf2ccdc))
* **task:** fix reminder for tasks ([a7651e5](https://github.com/Alinto/sogo/commit/a7651e56c53a4dc33892d86f404a132a2b8af83a))
* **ui:** add css class for login page ([a077512](https://github.com/Alinto/sogo/commit/a077512e34bf42933457b92613b348ff2e06642a))
* **calendar:** don't allocate and copy all children for each time we call _filterComponent: ([481a9bf](https://github.com/Alinto/sogo/commit/481a9bf1de1da8e07b5ed4c1786aac89d19ca6c3))
* **core:** store translations in a globally static NSMutableDictionary ([f48f27c](https://github.com/Alinto/sogo/commit/f48f27c812466ce806ab60b43ebe5a2bfc97ed0a))
### Localization
* **ar:** Update Arabic translations ([6c3e661](https://github.com/Alinto/sogo/commit/6c3e66142f50c68ee9b1435e5d6961573e7445d4))
* **bg_BG:** Update Bulgarian translations ([4585293](https://github.com/Alinto/sogo/commit/4585293d999152e6c7b54f00f73f925051a4ed64))
* **bs_BA:** Update Bosnian translations ([4461122](https://github.com/Alinto/sogo/commit/446112269705ae1565a21d3e39e4665c172fc3d4))
* **ca:** Update Catalan translations ([b77129e](https://github.com/Alinto/sogo/commit/b77129e2e7608f163eeeb1c4ed7e35fb5558c3cb))
* **cs:** Update Czech translations ([f252e0e](https://github.com/Alinto/sogo/commit/f252e0e2c271118cceb2979a828f5220350ba57f))
* **cy:** Update Welsh translations ([6425a62](https://github.com/Alinto/sogo/commit/6425a62e1ab8900dc83df5ca165eb92718856886))
* **da_DK:** Update Danish translations ([ae293ec](https://github.com/Alinto/sogo/commit/ae293ec3ce7488530199e82bd7bde50b2d506a43))
* **de:** Update German translations ([95e1937](https://github.com/Alinto/sogo/commit/95e19379f6fa698f54a09d7b7bcb4cfe16b4c358))
* **es_AR:** Update SpanishArgentina translations ([07e9d34](https://github.com/Alinto/sogo/commit/07e9d34865e57fa64f8db1b7ed4a5a67a0c1f234))
* **es_ES:** Update SpanishSpain translations ([c755ab3](https://github.com/Alinto/sogo/commit/c755ab3b4ea5ecad2c98d396d6bca6d873d0f1de))
* **eu:** Update Basque translations ([b96e531](https://github.com/Alinto/sogo/commit/b96e531f662a41802bd83e54e4a8055987d36164))
* **fi:** Update Finnish translations ([c0c506f](https://github.com/Alinto/sogo/commit/c0c506f9103b12ed5a39b340c4bccac500a2f6a8))
* **fr:** Update French translations ([a914fd4](https://github.com/Alinto/sogo/commit/a914fd4151e5565d4f168819c2664dc460587dec))
* **gl:** Update Galician translations ([f017fef](https://github.com/Alinto/sogo/commit/f017fef4b2a86f210f36bd5e62afe37c7bba3a18))
* **he:** Update Hebrew translations ([070705a](https://github.com/Alinto/sogo/commit/070705acfaa65ad435c1d2fa659e4b1f333b59a8))
* **hr_HR:** Update Croatian translations ([e662f10](https://github.com/Alinto/sogo/commit/e662f10389795e281abd283775f0d168a519e25d))
* **hu:** Update Hungarian translations ([799e8c2](https://github.com/Alinto/sogo/commit/799e8c21af79b2a8beb082a9d56a238aee30ae4a))
* **id_ID:** Update Indonesian translations ([56e4929](https://github.com/Alinto/sogo/commit/56e4929ca78c105dde470a6d26749b1328fad47f))
* **is:** Update Icelandic translations ([401e2f5](https://github.com/Alinto/sogo/commit/401e2f51cd3a69afa72fb76ffeb8fc91a5779cca))
* **it:** Update Italian translations ([1bb74c7](https://github.com/Alinto/sogo/commit/1bb74c75227f858d680035a5eccd7c5ef954f869))
* **ja:** Update Japanese translations ([9a295c5](https://github.com/Alinto/sogo/commit/9a295c5944886df95b941f716fc5e6b4c62525b7))
* **kk:** Update Kazakh translations ([6514fbb](https://github.com/Alinto/sogo/commit/6514fbb8f1c2745dd44be49c72da88937fcf107f))
* **ko:** Update Korean translations ([ed91211](https://github.com/Alinto/sogo/commit/ed9121175aa6164a73987a247cebe47e53676529))
* **lt:** Update Lithuanian translations ([2b455fe](https://github.com/Alinto/sogo/commit/2b455fe587f96700c4398538b995680251660ac1))
* **lv:** Update Latvian translations ([ad7dc8f](https://github.com/Alinto/sogo/commit/ad7dc8f45ee316c4d39ebf5fa71207947b4be2f8))
* **mk_MK:** Update Macedonian translations ([798bed5](https://github.com/Alinto/sogo/commit/798bed54e2eb0f76f26dc6c6c423285c565b9888))
* **nb_NO:** Update NorwegianBokmal translations ([eab6d9f](https://github.com/Alinto/sogo/commit/eab6d9f2492eccc2397c3ad49ab284223cb8771c))
* **nl:** Update Dutch translations ([b42882b](https://github.com/Alinto/sogo/commit/b42882b564ad9aa1b510b00d06da21688d959785))
* **nn_NO:** Update NorwegianNynorsk translations ([3a442f1](https://github.com/Alinto/sogo/commit/3a442f1b3d38350a5544f0fb62718f45b70c37ad))
* **pl:** Update Polish translations ([16fcb46](https://github.com/Alinto/sogo/commit/16fcb46c4be26497d12be712c5bacf0f0056a5b3))
* **pt_BR:** Update BrazilianPortuguese translations ([9d277c3](https://github.com/Alinto/sogo/commit/9d277c3f157e21183648609e5bee429559e87a63))
* **pt:** Update Portuguese translations ([972ffcc](https://github.com/Alinto/sogo/commit/972ffcc0c6f4f67da5557da28b6c5af87d632b96))
* **ro_RO:** Update Romanian translations ([ec4d780](https://github.com/Alinto/sogo/commit/ec4d7807d994836218c6ba9c5979283623a520d4))
* **ru:** Update Russian translations ([1a80fd6](https://github.com/Alinto/sogo/commit/1a80fd6284750cc9997e6cbbafcdf86765032405))
* **sk:** Update Slovak translations ([0f24c17](https://github.com/Alinto/sogo/commit/0f24c175163e2a000d6cace4d9302cae384f3b49))
* **sl_SI:** Update Slovenian translations ([645be8f](https://github.com/Alinto/sogo/commit/645be8fcc53cd2729dad9906e66a8f630cffaf52))
* **sr_ME@latin:** Update Montenegrin translations ([3dc9b90](https://github.com/Alinto/sogo/commit/3dc9b9099223940ec4a4f660d499ac450398d6cc))
* **sr@latin:** Update SerbianLatin translations ([c675dbf](https://github.com/Alinto/sogo/commit/c675dbfaa70755abf4300462f538dfa878c7c969))
* **sr:** Update Serbian translations ([dd367b0](https://github.com/Alinto/sogo/commit/dd367b0e94b74dccfc862d9ca07906cc16234965))
* **sv:** Update Swedish translations ([2ebb637](https://github.com/Alinto/sogo/commit/2ebb63767e53c39bc982d9959dabacfdce8b9b19))
* **th:** Update Thai translations ([f86a32d](https://github.com/Alinto/sogo/commit/f86a32d0a148b8465a01f098855dc58470c1a689))
* **tr_TR:** Update TurkishTurkey translations ([8c38c9c](https://github.com/Alinto/sogo/commit/8c38c9ce038e902d4b79f2093448ffec2c1f1d55))
* **uk:** Update Ukrainian translations ([5021376](https://github.com/Alinto/sogo/commit/5021376daf92c95a69afa2a2d99cf559f858d478))
* **zh_CN:** Update ChineseChina translations ([22ab0b3](https://github.com/Alinto/sogo/commit/22ab0b3c751f7c20c234c1824552aaa4c661f983))
* **zh_TW:** Update ChineseTaiwan translations ([c7a519c](https://github.com/Alinto/sogo/commit/c7a519ca124121e259a00473e6163cbd93e16aa4))
### [5.12.3](https://github.com/Alinto/sogo/compare/SOGo-5.12.2...SOGo-5.12.3) (2025-07-12)
+126 -143
View File
@@ -1,5 +1,4 @@
Installation and Configuration Guide
====================================
= Installation and Configuration Guide
////
This file is part of the SOGo project.
@@ -10,8 +9,8 @@ Installation and Configuration Guide
////
include::includes/global-attributes.asciidoc[]
About this Guide
----------------
== About this Guide
This guide will walk you through the installation and configuration of
the SOGo solution. It also covers the installation and configuration of
@@ -23,8 +22,8 @@ The instructions are based on version {release_version} of SOGo.
The latest version of this guide is available
at https://www.sogo.nu/support.html#/documentation.
Introduction
------------
== Introduction
SOGo is a free and modern scalable groupware server. It offers shared
calendars, address books, and emails through your favourite Web browser
@@ -48,8 +47,8 @@ device, or Outlook 2013/2016
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found at https://sogo.nu/
Architecture and Compatibility
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Architecture and Compatibility
image::images/architecture.png[System Architecture, 400, 964]
@@ -61,11 +60,11 @@ protocol are also supported.
To install and configure the Outlook CalDav Synchronizer, please refer
to the _Outlook Connector Configuration Guide_.
System Requirements
-------------------
Assumptions
~~~~~~~~~~~
== System Requirements
=== Assumptions
SOGo reuses many components in an infrastructure. Thus, it requires the
following:
@@ -104,8 +103,8 @@ components, together with version numbers:
More recent versions of the software mentioned above can also be used.
Minimum Hardware Requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Minimum Hardware Requirements
The following table provides hardware recommendations for the server,
desktops and mobile devices:
@@ -157,8 +156,8 @@ Linux
Microsoft ActiveSync.
|=======================================================================
Operating System Requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Operating System Requirements
The following operating systems are currently supported by SOGo:
@@ -182,16 +181,16 @@ directly to the SOGo website at https://sogo.nu/faq/installation.html.
Note that once the SOGo packages are installed under Debian and Ubuntu,
this guide can be followed in order to fully configure SOGo.
Installation
------------
== Installation
This section will guide you through the installation of SOGo together
with its dependencies. The steps described here apply to an RPM-based
installation for a Red Hat or CentOS 7 distribution. Most of these steps
should apply to all supported operating systems.
Software Downloads
~~~~~~~~~~~~~~~~~~
=== Software Downloads
**In order to access the community build, go to https://www.sogo.nu/download.html[SOGo website]
and select "Development (nightly builds)" at the bottom of the page.**
@@ -255,8 +254,8 @@ sed -i '/enabled=1/a exclude=gnustep* ytnef*' /etc/yum.repos.d/epel.repo
For more information on EPEL, visit http://fedoraproject.org/wiki/EPEL/.
Software Installation
~~~~~~~~~~~~~~~~~~~~~
=== Software Installation
Once the yum configuration file has been created, you are now ready to
install SOGo and its dependencies. To do so, proceed with the following
@@ -276,8 +275,8 @@ for Oracle. The installation command will thus look like this:
Once completed, SOGo will be fully installed on your server. You are now
ready to configure it.
Configuration
-------------
== Configuration
In this section, you'll learn how to configure SOGo to use your existing
LDAP, SMTP and database servers. As previously mentioned, we assume that
@@ -285,8 +284,8 @@ those components run on the same server on which SOGo is being
installed. If this is not the case, please adjust the configuration
parameters to reflect those changes.
GNUstep Environment Overview
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== GNUstep Environment Overview
SOGo makes use of the GNUstep environment. GNUstep is a free software
implementation of the OpenStep specification which provides many
@@ -319,8 +318,8 @@ wrapped within curly brackets `{ [configuration] }`. If SOGo refuses to
start due to syntax errors in its configuration file, `plparse` is helpful
for finding these, as it indicates the line containing the problem.
Preferences Hierarchy
~~~~~~~~~~~~~~~~~~~~~
=== Preferences Hierarchy
SOGo supports domain names segregation, meaning that you can separate
multiple groups of users within one installation of SOGo. A user
@@ -350,8 +349,8 @@ following abbreviations in the tables of this document:
Remember that the hierarchy paradigm allow the default value of a
parameter to be defined at a parent level.
General Preferences
~~~~~~~~~~~~~~~~~~~
=== General Preferences
The following table describes the general parameters that can be set:
@@ -879,8 +878,8 @@ Obiously, if your users can connect without specifying a domain, let this parame
[[Secret-for-sensitive-data]]
Secret for sensitive data
~~~~~~~~~~~~~~~~~~~~~~~~~
=== Secret for sensitive data
_Since 5.10_
@@ -974,8 +973,7 @@ sogo-tool user-preferences unset default <user> AuxiliaryMailAccounts
user being the full mail address or just the username if domainless. After that, the user will have to set its auxiliary accounts again.
Authentication using LDAP
~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authentication using LDAP
SOGo can use a LDAP server to authenticate users and, if desired, to
provide global address books. SOGo can also use an SQL backend for this
@@ -1385,8 +1383,8 @@ Defaults to `NO` when unset.
|=======================================================================
LDAP Attributes Indexing
~~~~~~~~~~~~~~~~~~~~~~~~
=== LDAP Attributes Indexing
To ensure proper performance of the SOGo application, the following LDAP
attributes must be fully indexed:
@@ -1402,8 +1400,8 @@ attributes must be fully indexed:
Please refer to the documentation of the software you use in order to
index those attributes.
LDAP Attributes Mapping
~~~~~~~~~~~~~~~~~~~~~~~
=== LDAP Attributes Mapping
Some LDAP attributes are mapped to contacts attributes in the SOGo UI.
The table below list most of them. It is possible to override these by
@@ -1463,8 +1461,8 @@ mapping = {
|Photo |photo
|===
Authenticating using C.A.S.
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authenticating using C.A.S.
SOGo natively supports C.A.S. authentication. For activating C.A.S.
authentication you need first to make sure that the
@@ -1568,9 +1566,7 @@ connection properly.
[[openid-section]]
Authenticating using OPENID
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authenticating using OPENID
SOGo natively supports OPENID authentication. For activating OpenId authentication you need first to make sure that
_SOGoAuthenticationType_ is set to `openid`,
@@ -1643,8 +1639,8 @@ the session will stays in the table and be useless. That's why a new sogo-tool c
You can put it in a cron to do that periodicly. +
See _<<sogo-tool-clean-openid-sessions,sogo-tool clean-openid-sessions>>_.
Authenticating using SAML2
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authenticating using SAML2
SOGo natively supports SAML2 authentication. Please refer to the documentation of your identity
provider and the SAML2 configuration keys that are listed above for proper setup. Once a SOGo
@@ -1677,8 +1673,7 @@ _NGImap4AuthMechanism_ is configured to use the `SAML` mechanism. If you
make use of the CrudeSAML PAM plugin, this value may be left empty.
Database Configuration
~~~~~~~~~~~~~~~~~~~~~~
=== Database Configuration
SOGo requires a relational database system in order to store
appointments, tasks and contacts information. It also uses the database
@@ -1925,10 +1920,9 @@ calendar.
Ensure the computer used for the test has emoji fonts installed.
[[Authentication-using-SQL]]
Authentication using SQL
~~~~~~~~~~~~~~~~~~~~~~~~
[[Authentication-using-SQL]]
=== Authentication using SQL
SOGo can use a SQL-based database server for authentication. The
configuration is very similar to LDAP-based authentication.
@@ -2165,8 +2159,8 @@ or username@domain.tld
Note that groups are currently not supported for SQL-based
authentication sources.
SMTP Server Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
=== SMTP Server Configuration
SOGo makes use of a SMTP server to send emails from the Web interface,
iMIP/iTIP messages and various notifications.
@@ -2225,8 +2219,8 @@ Possible values are:
Defaults to `NO` when unset.
|=======================================================================
IMAP Server Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
=== IMAP Server Configuration
SOGo requires an IMAP server in order to let users consult their email
messages, manage their folders and more.
@@ -2394,8 +2388,8 @@ permissions for the individual user.
The default prefix is `$`. 
|=======================================================================
Web Interface Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Web Interface Configuration
The following additional parameters only affect the Web interface
behaviour of SOGo.
@@ -2902,8 +2896,8 @@ SOGoMailJunkSettings = {
sent by SOGo. Defaults to `NO` when unset.
|=======================================================================
SOGo Configuration Summary
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== SOGo Configuration Summary
The complete SOGo configuration file `/etc/sogo/sogo.conf` should look
like this:
@@ -2951,10 +2945,9 @@ like this:
}
----
[[multi-domains-configuration]]
Multi-domains Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~
[[multi-domains-configuration]]
=== Multi-domains Configuration
If you want your installation to isolate two groups of users, you must
define a distinct authentication source for each _domain_. Your domain keys
@@ -3050,8 +3043,8 @@ Defaults to an empty array, which means domains are isolated from each
other.
|=======================================================================
Apache Configuration
~~~~~~~~~~~~~~~~~~~~
=== Apache Configuration
The SOGo configuration for Apache is located in
`/etc/httpd/conf.d/SOGo.conf`.
@@ -3080,8 +3073,8 @@ The default configuration will use `mod_proxy` and `mod_headers` to
relay requests to the `sogod` parent process. This is suitable for small
to medium deployments.
Starting Services
~~~~~~~~~~~~~~~~~
=== Starting Services
Once SOGo if fully installed and configured, start the services using
the following command:
@@ -3097,8 +3090,8 @@ modules and configuration files were added:
Finally, you should also make sure that the `memcached` service is
started and that it is also automatically started at boot time.
_Cronjob_ — EMail reminders
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Cronjob_ — EMail reminders
SOGo allows you to set email-based reminders for events and tasks. To
enable this, you must enable the `SOGoEnableEMailAlarms` preference and
@@ -3125,8 +3118,8 @@ SOGoSMTPMasterUserUsername = "foo";
SOGoSMTPMasterUserPassword = "bar";
```
_Cronjob_ — Vacation messages activation and expiration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Cronjob_ — Vacation messages activation and expiration
When vacation messages are enabled (see the parameter
_SOGoVacationEnabled_), users can set an activation or expiration date
@@ -3147,8 +3140,8 @@ The _cronjob_ should look like this:
0 0 * * * sogo /usr/sbin/sogo-tool update-autoreply -p /etc/sogo/sieve.creds
----
_Password_ — Force user password change at login
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Password_ — Force user password change at login
The following commands force user to change his password at login :
@@ -3162,11 +3155,11 @@ Disable :
/usr/sbin/sogo-tool user-preferences unset settings [USER] ForceResetPassword
----
Managing User Accounts
----------------------
Creating the SOGo Administrative Account
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
== Managing User Accounts
=== Creating the SOGo Administrative Account
First, create the SOGo administrative account in your LDAP server. The
following LDIF file (`sogo.ldif`) can be used as an example:
@@ -3193,8 +3186,8 @@ administrative account using the following command:
ldappasswd -h 127.0.0.1 -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=sogo,ou=users,dc=acme,dc=com -s qwerty
Creating a User Account
~~~~~~~~~~~~~~~~~~~~~~~
=== Creating a User Account
SOGo uses LDAP directories to authenticate users. Use the following LDIF
file (`jdoe.ldif`) as an example to create a SOGo user account:
@@ -3227,8 +3220,8 @@ easier. These GUI utilities can make use of templates to create and
pre-configure typical user accounts or any standardized LDAP record,
along with the correct object classes, fields and default values.
Microsoft Enterprise ActiveSync
-------------------------------
=== Microsoft Enterprise ActiveSync
SOGo supports the Microsoft ActiveSync protocol.
@@ -3364,8 +3357,8 @@ and send an email to iplicreq@microsoft.com
Alinto provides this software for free, but is not responsible for
anything related to its usage.
Microsoft Enterprise ActiveSync Tuning
--------------------------------------
== Microsoft Enterprise ActiveSync Tuning
First of all, it is important to know that most EAS devices will keep
HTTP connections open to SOGo (and thus, Apache) for a long time. This
@@ -3440,8 +3433,8 @@ SOGoMaximumSyncInterval = 3540;
SOGoInternalSyncInterval = 60;
----
S/MIME Support in SOGo
----------------------
== S/MIME Support in SOGo
SOGo supports S/MIME email signing and encryption. When receiving
S/MIME signed emails, SOGo automatically extracts the PKCS (Public-Key
@@ -3459,11 +3452,10 @@ please have a look at Actalis:
https://www.actalis.it/products/certificates-for-secure-electronic-mail.aspx
Using SOGo
----------
== Using SOGo
SOGo Web Interface
~~~~~~~~~~~~~~~~~~
=== SOGo Web Interface
To acces the SOGo Web Interface, point your Web browser, which is
running from the same server where SOGo was installed, to the following
@@ -3472,8 +3464,8 @@ URL: http://127.0.0.1/SOGo.
Log in using the "jdoe" user and the "qwerty" password. The underlying
database tables will automatically be created by SOGo.
Mozilla Thunderbird and Lightning
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Mozilla Thunderbird and Lightning
Alternatively, you can access SOGo with a GroupDAV and a CalDAV client.
A typical well-integrated setup is to use Mozilla Thunderbird and
@@ -3515,8 +3507,8 @@ To access your personal calendar:
`http://127.0.0.1/SOGo/dav/jdoe/Calendar/personal/`
* Click on Continue.
Apple Calendar (macOS, iOS, iPadOS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Apple Calendar (macOS, iOS, iPadOS)
Apple Calendar on macOS, iOS, and iPadOS can also be used
as a client application for SOGo.
@@ -3534,8 +3526,8 @@ 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
~~~~~~~~~~~~~~~~~
=== Apple AddressBook
Since Mac OS X 10.6 (Snow Leopard), Apple AddressBook can be configured
to use SOGo.
@@ -3583,8 +3575,8 @@ 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
~~~~~~~~~~~~~~~~~~~~
=== Microsoft ActiveSync
You can synchronize contacts, emails, events and tasks from SOGo with
any mobile devices that support Microsoft ActiveSync. Microsoft Outlook
@@ -3593,8 +3585,9 @@ 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
---------------
== 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:
@@ -3603,8 +3596,8 @@ the sogo package on Debian/Ubuntu but must be installed manually on RHEl/CentOS:
*_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
~~~~~~~~~~~~~~~~~~~~~~~~
=== 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.
@@ -3685,8 +3678,8 @@ sogo-tool restore -F "Contacts/personal" tmp/backup user1
sogo-tool restore -F "Calendar/60C8-65323D80-7-4D9F7D80" tmp/backup user1
----
sogo-tool checkup
~~~~~~~~~~~~~~~~~
=== sogo-tool checkup
Check the events and contacts data's integrity of a user
@@ -3717,8 +3710,8 @@ sogo-tool checkup -d user1
[[sogo-tool-clean-openid-sessions]]
sogo-tool clean-openid-sessions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool clean-openid-sessions
Obviously only usefull if you have set SOGo with openId authentication.
Will clean all expired openId sessions from the database.
@@ -3730,8 +3723,8 @@ Example:
sogo-tool clean-openid-sessions
----
sogo-tool cleanup
~~~~~~~~~~~~~~~~~
=== sogo-tool cleanup
Will purge all user's deleted events and contacts which the deletion is older than a number of days.
@@ -3755,8 +3748,7 @@ Purged 5 records from folder /Users/user2/Calendar/personal
----
sogo-tool create-folder
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool create-folder
Create a folder (Calendar or Address Book) for a user.
@@ -3773,8 +3765,7 @@ sogo-tool create-folder user2 Calendar Pro_Calendar
----
sogo-tool dump-defaults
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool dump-defaults
Output all current defaults value of GNUstep and SOGo (sogo.conf)
@@ -3791,8 +3782,8 @@ sogo-tool dump-defaults all
sogo-tool dump-defaults -f /tmp/foo/conf.xml
----
sogo-tool expire-sessions
~~~~~~~~~~~~~~~~~~~~~~~~~
=== 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
@@ -3811,8 +3802,8 @@ sogo-tool expire-sessions 160 #Will remove session which last activity is ol
sogo-tool expire-sessions 0 #Will remove session which last activity is older than 0 minutes.
----
sogo-tool manage-acl
~~~~~~~~~~~~~~~~~~~~
=== sogo-tool manage-acl
Manage access-control list (ACL) of a user for folders (Calendar and Address Book).
@@ -3883,8 +3874,8 @@ Example:
sogo-tool manage-acl unsubscribe sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2
----
sogo-tool manage-eas
~~~~~~~~~~~~~~~~~~~~
=== sogo-tool manage-eas
Manage EAS folders
@@ -3914,8 +3905,8 @@ sogo-tool manage-eas mergevcard janedow androidc316986417 YES
sogo-tool manage-eas mergevevent janedow androidc316986417 YES
----
sogo-tool remove
~~~~~~~~~~~~~~~~
=== 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.
@@ -3939,8 +3930,8 @@ Deleting /Users/user2/Contacts/B087-65363400-7-374DA380
Deleting /Users/user2/Contacts/personal
----
sogo-tool remove-doubles
~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool remove-doubles
remove duplicate contacts from the specified user addressbook
@@ -3965,8 +3956,8 @@ sogo-tool remove-doubles user1 personal
sogo-tool remove-doubles user2 489-65376E80-1-2D2BA000
----
sogo-tool rename-user
~~~~~~~~~~~~~~~~~~~~~
=== 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.
@@ -3984,8 +3975,8 @@ Example:
sogo-tool rename-user old_username new_username
----
sogo-tool truncate-calendar
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool truncate-calendar
Remove old calendar entries from the specified user calendar.
@@ -4015,8 +4006,7 @@ Removing 1 records...
Removed 1 records.
----
sogo-tool update-autoreply
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== 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,
@@ -4036,8 +4026,7 @@ Example:
[[sogo-tool-update-secret]]
sogo-tool update-secret
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool update-secret
_New in 5.10_
@@ -4063,8 +4052,7 @@ If your data are already encrypted with 'oldSecret' but you want to decrypt them
sogo-tool update-secret -o oldSecret
----
sogo-tool user-preferences
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool user-preferences
Get, set or unset user defaults / settings in the database.
@@ -4123,8 +4111,7 @@ sogo-tool user-preferences set defaults user1 Forward -f /path/filename -p cred
----
API REST
--------
== API REST
Starting from 5.12.2, an API with two endpoints is available.
All response will be on json format. In case of errors, the message will be:
@@ -4133,8 +4120,7 @@ All response will be on json format. In case of errors, the message will be:
```
with an explicit message
API server url
~~~~~~~~~~~~~~
=== API server url
_<scheme>_://_<domain>_/SOGo/SOGoAPI/_<action>_
@@ -4142,8 +4128,7 @@ _<scheme>_://_<domain>_/SOGo/SOGoAPI/_<action>_
• *domain* : domain or ip:port of SOGo's server
• *action* : name of the action. No action does the Version action described below.
Authentication
~~~~~~~~~~~~~~
=== Authentication
Somes actions needs to be authenticated. There is two ways to do so:
@@ -4165,8 +4150,8 @@ Add a header *Auhtorization* with value:
*acces_token* is from the https://connect2id.com/products/server/docs/api/token#url[openid protocol]. It has to be fetch with the scope `openid`.
Action - Version
~~~~~~~~~~~~~~~~
=== Action - Version
* *URL*: <scheme>://<domain>/SOGo/SOGoAPI/Version
* *Authentication needed*: NO
* *HTTP method allowed*: GET
@@ -4180,8 +4165,8 @@ Action - Version
}
```
Action - UserFolder
~~~~~~~~~~~~~~~~~~~
=== Action - UserFolder
* *URL*: <scheme>://<domain>/SOGo/SOGoAPI/UserFolder
* *Authentication needed*: YES
* *HTTP method allowed*: GET
@@ -4225,8 +4210,7 @@ A folder info is a dict with:
** *name*: Name of the folder.
** *url*: Dav link of the folder.
Errors and messages
~~~~~~~~~~~~~~~~~~~
=== Errors and messages
Complete http response is `{“error:” : <message>}`.
*<action>* is the one used for the request: `<scheme>://<domain>/SOGo/SOGoAPI/<action>`
@@ -4273,8 +4257,7 @@ To have more logs you can add `SOGoAPIDebugEnabled = YES;` to your sogo.conf.
Upgrading
---------
== Upgrading
This section describes what needs to be done when upgrading to the
current version of SOGo from the previous release.
@@ -12,8 +12,8 @@
////
Additional Information
----------------------
== Additional Information
For more information, please consult the online FAQs (Frequently Asked
Questions) :
@@ -12,8 +12,7 @@
////
Commercial Support and Contact Information
------------------------------------------
== Commercial Support and Contact Information
For any questions or comments, do not hesitate to contact us by writing
an email to contact@sogo.nu.
+12 -12
View File
@@ -214,10 +214,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR(4096) NOT NULL,"
@" c_old_session VARCHAR(4096) NULL,"
@" c_user_session TEXT NOT NULL,"
@" c_old_session TEXT NULL,"
@" c_session_started INT4 NOT NULL,"
@" c_refresh_token VARCHAR(4096) NULL,"
@" c_refresh_token TEXT NULL,"
@" c_access_token_expires_in INT4 NULL,"
@" c_refresh_token_expires_in INT4 NULL)");
@@ -274,7 +274,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(4096) NOT NULL,"
@" c_value TEXT NOT NULL,"
@" c_creationdate INT4 NOT NULL,"
@" c_lastseen INT4 NOT NULL)");
@@ -375,10 +375,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR(4096) NOT NULL,"
@" c_old_session VARCHAR(4096) NULL,"
@" c_user_session TEXT NOT NULL,"
@" c_old_session TEXT NULL,"
@" c_session_started INT4 NOT NULL,"
@" c_refresh_token VARCHAR(4096) NULL,"
@" c_refresh_token TEXT NULL,"
@" c_access_token_expires_in INT4 NULL,"
@" c_refresh_token_expires_in INT4 NULL)");
@@ -435,7 +435,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(4096) NOT NULL,"
@" c_value TEXT NOT NULL,"
@" c_creationdate INT NOT NULL,"
@" c_lastseen INT NOT NULL)");
@@ -536,10 +536,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR2(4096) NOT NULL,"
@" c_old_session VARCHAR2(4096) NULL,"
@" c_user_session VARCHAR2(8192) NOT NULL,"
@" c_old_session VARCHAR2(8192) NULL,"
@" c_session_started INTEGER NOT NULL,"
@" c_refresh_token VARCHAR2(4096) NULL,"
@" c_refresh_token VARCHAR2(8192) NULL,"
@" c_access_token_expires_in INTEGER NULL,"
@" c_refresh_token_expires_in INTEGER NULL)");
@@ -595,7 +595,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR2(255) PRIMARY KEY,"
@" c_value VARCHAR2(4096) NOT NULL,"
@" c_value VARCHAR2(8192) NOT NULL,"
@" c_creationdate INTEGER NOT NULL,"
@" c_lastseen INTEGER NOT NULL)");
+7 -2
View File
@@ -86,8 +86,13 @@
tzId = [self value: 0 ofAttribute: @"tzid"];
if ([tzId length])
{
calendar = (iCalCalendar *) [self searchParentOfClass: [iCalCalendar class]];
timeZone = [calendar timeZoneWithId: tzId];
//Hack, get timezone inf from sogo and not from the event VTIMEZONE as it can be incorrect/incomplete
timeZone = [iCalTimeZone timeZoneForName: tzId];
if(!timeZone)
{
calendar = (iCalCalendar *) [self searchParentOfClass: [iCalCalendar class]];
timeZone = [calendar timeZoneWithId: tzId];
}
//if (!timeZone)
//[self logWithFormat: @"timezone '%@' not found in calendar", tzId];
}
+4 -4
View File
@@ -142,7 +142,7 @@ CREATE TABLE sogo_quick_contact (
CREATE TABLE sogo_sessions_folder (
c_id varchar(255) NOT NULL,
c_value varchar(4096) NOT NULL,
c_value text NOT NULL,
c_creationdate int(11) NOT NULL,
c_lastseen int(11) NOT NULL,
PRIMARY KEY (c_id)
@@ -166,10 +166,10 @@ CREATE TABLE sogo_admin (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE sogo_opend_id (
c_user_session varchar(4096) NOT NULL,
c_old_session varchar(4096) DEFAULT '',
c_user_session text NOT NULL,
c_old_session text DEFAULT '',
c_session_started int(11) NOT NULL,
c_refresh_token varchar(4096) DEFAULT '',
c_refresh_token text DEFAULT '',
c_access_token_expires_in int(11) DEFAULT '',
c_refresh_token_expires_in int(11) DEFAULT NULL,
PRIMARY KEY (c_user_session)
@@ -1133,8 +1133,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId inArray: ma];
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange] && recordIndex == -1) {
[self warnWithFormat:
@"missing exception record for recurrence-id %@ (uid %@), ma = %@, dr = %@, rir = %@",
recurrenceId, [component uid], ma, dateRange, recurrenceIdRange];
@"missing exception record for recurrence-id %@ (uid %@), dr = %@, rir = %@",
recurrenceId, [component uid], dateRange, recurrenceIdRange];
}
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange] && recordIndex != -1)
{
+15 -10
View File
@@ -65,6 +65,9 @@
#import "iCalRepeatableEntityObject+SOGo.h"
#import "SOGoCalendarComponent.h"
static NSArray *allowed_tags = nil;
@implementation SOGoCalendarComponent
+ (SOGoWebDAVAclManager *) webdavAclManager
@@ -210,7 +213,6 @@
SOGoUser *calendarOwner;
NSEnumerator *children;
CardElement *element;
NSArray *tags;
int classification;
@@ -231,22 +233,25 @@
summary = [self labelForKey: [NSString stringWithFormat: @"%@_class%d",
type, classification]
inContext: context];
tags = [NSArray arrayWithObjects: @"DTSTAMP", @"DTSTART", @"DTEND", @"DUE", @"EXDATE", @"EXRULE", @"RRULE", @"RECURRENCE-ID", nil];
if(!allowed_tags)
allowed_tags = [[NSArray arrayWithObjects: @"DTSTAMP", @"DTSTART", @"DTEND", @"DUE", @"EXDATE", @"EXRULE", @"RRULE", @"RECURRENCE-ID", nil] retain];
uid = [[component uid] asCryptedPassUsingScheme: @"ssha256"
withSalt: [[settings userPublicSalt] dataUsingEncoding: NSASCIIStringEncoding]
andEncoding: encHex
keyPath: nil];
children = [[[[component children] copy] autorelease] objectEnumerator];
children = [[component children] objectEnumerator];
NSMutableArray *to_remove = [NSMutableArray arrayWithCapacity: 8];
while ((element = [children nextObject]))
{
tag = [element tag];
if (![tags containsObject: [tag uppercaseString]])
[component removeChild: element];
if (![allowed_tags containsObject: [tag uppercaseString]])
[to_remove addObject: element];
}
[component removeChildren: to_remove];
[component setSummary: summary];
[component setUid: uid];
}
@@ -885,7 +890,7 @@
mailDate = [[NSCalendarDate date] rfc822DateString];
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: subject forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: senderEmail] forKey: @"message-id"];
if ([msgType length] > 0)
[headerMap setObject: msgType forKey: @"x-sogo-message-type"];
msg = [NGMimeMessage messageWithHeader: headerMap];
@@ -974,7 +979,7 @@
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: [[p getSubject] asQPSubjectString: @"UTF-8"]
forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: [[attendee mailAddress] pureEMailAddress]] forKey: @"message-id"];
[headerMap setObject: @"1.0" forKey: @"MIME-Version"];
if (textOnly)
@@ -1163,7 +1168,7 @@
mailDate = [[NSCalendarDate date] rfc822DateString];
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: [page getSubject] forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: senderEmail] forKey: @"message-id"];
[headerMap setObject: @"1.0" forKey: @"MIME-Version"];
[headerMap setObject: @"text/html; charset=utf-8"
forKey: @"content-type"];
+10
View File
@@ -107,6 +107,7 @@
BOOL isAllDayStartDate, isAllDayDueDate;
NSCalendarDate *startDate, *dueDate, *completedDate;
NSInteger percent;
NSString *owner;
SOGoUserDefaults *ud;
iCalDateTime *todoStartDate, *todoDueDate;
iCalTimeZone *tz;
@@ -230,6 +231,15 @@
}
else
[self setPercentComplete: @""];
//To make an ics conforme with outlook live (bouh), valarm must be the last element of vevent
//Try to set it here
o = [data objectForKey: @"alarm"];
if ([o isKindOfClass: [NSDictionary class]])
{
owner = [data objectForKey: @"owner"];
[self _setAlarm: o forOwner: owner];
}
}
- (NSMutableDictionary *) quickRecordFromContent: (NSString *) theContent
+1 -1
View File
@@ -25,7 +25,7 @@
@interface NSString (SOGoExtension)
+ (NSString *) generateMessageID;
+ (NSString *) generateMessageID: (NSString *) mailOrDomain;
- (NSString *) htmlToText;
- (NSString *) htmlByExtractingImages: (NSMutableArray *) theImages;
- (NSString *) stringByConvertingCRLNToHTML;
+17 -5
View File
@@ -560,15 +560,27 @@
@implementation NSString (SOGoExtension)
+ (NSString *) generateMessageID
+ (NSString *) generateMessageID: (NSString *) mailOrDomain
{
NSMutableString *messageID;
NSString *pGUID;
NSString *_domain;
NSRange r;
messageID = [NSMutableString string];
[messageID appendFormat: @"<%@", [SOGoObject globallyUniqueObjectId]];
pGUID = [[NSProcessInfo processInfo] globallyUniqueString];
[messageID appendFormat: @"@%u>", (unsigned int)[pGUID hash]];
[messageID appendFormat: @"<%@", [SOGoObject mailUniqueMessageId]];
if(mailOrDomain)
{
r = [mailOrDomain rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
//Its the full email not a domain
_domain = [mailOrDomain substringFromIndex: (r.location + r.length)];
}
else
_domain = mailOrDomain;
[messageID appendFormat: @"@%@>", _domain];
}
return [messageID lowercaseString];
}
+1 -1
View File
@@ -222,7 +222,7 @@ static NSString *userAgent = nil;
messageID = [headers objectForKey: @"message-id"];
if (!messageID)
{
messageID = [NSString generateMessageID];
messageID = [NSString generateMessageID: [[newHeaders objectForKey: @"from"] pureEMailAddress]];
[headers setObject: messageID forKey: @"message-id"];
}
+4
View File
@@ -142,6 +142,10 @@
else
imapAuthMech = nil;
//If ActiveSync, force the plain mech
if([[[[self context] request] requestHandlerKey] isEqualToString:@"Microsoft-Server-ActiveSync"])
imapAuthMech = @"plain";
return [NGImap4ConnectionManager defaultConnectionManager: imapAuthMech];
}
+1
View File
@@ -27,6 +27,7 @@
@class NSArray;
@class NSString;
@class WOContext;
@class NSNull;
@interface NSObject (SOGoObjectUtilities)
+21 -9
View File
@@ -33,6 +33,9 @@
#import "NSObject+Utilities.h"
static NSMutableDictionary *translationCache = nil;
@implementation NSObject (SOGoObjectUtilities)
- (NSString *) jsonRepresentation
@@ -101,19 +104,28 @@
if (!bundle)
bundle = [NSBundle mainBundle];
languages = [[self _languagesForLabelsInContext: context] objectEnumerator];
if(!translationCache)
translationCache = [NSMutableDictionary new];
while (!label && (language = [languages nextObject]))
{
paths = [bundle pathsForResourcesOfType: @"strings"
inDirectory: [NSString stringWithFormat: @"%@.lproj",
language]
if (![translationCache objectForKey: language] || [[translationCache objectForKey: language] objectForKey: key] != [NSNull null]) {
paths = [bundle pathsForResourcesOfType: @"strings"
inDirectory: [NSString stringWithFormat: @"%@.lproj",
language]
forLocalization: language];
if ([paths count] > 0)
{
strings = [NSDictionary
dictionaryFromStringsFile: [paths objectAtIndex: 0]];
label = [strings objectForKey: key];
}
if ([paths count] > 0)
{
strings = [NSDictionary
dictionaryFromStringsFile: [paths objectAtIndex: 0]];
[translationCache setObject: strings forKey: language];
label = [strings objectForKey: key];
}
} else {
strings = [translationCache objectForKey: language];
label = [strings objectForKey: key];
}
}
if (!label)
label = key;
+3
View File
@@ -184,6 +184,9 @@ static int cssEscapingCount;
{
rangePtr->location += offset;
urlText = [selfCopy substringFromRange: *rangePtr];
//If we try to detect mail, check if the first char is @, meaning this is not an email
if([prefix isEqualToString: @"mailto:"] && [urlText characterAtIndex: 0] == '@')
continue;
newUrlText = [NSString stringWithFormat: @"<a rel=\"noopener\" href=\"%@%@\">%@</a>",
([urlText hasPrefix: prefix]? @"" : prefix),
urlText, urlText];
+4 -3
View File
@@ -49,7 +49,7 @@
- (BOOL) checkLogin: (NSString *) _login
password: (NSString *) _pwd
{
NSString *domain;
NSString *domain, *trueLogin;
SOGoSystemDefaults *sd;
SOGoCASSession *session;
SOGoPasswordPolicyError perr;
@@ -58,9 +58,10 @@
domain = nil;
perr = PolicyNoError;
trueLogin = [_login stringByReplacingString: @"%40"
withString: @"@"];
rc = ([[SOGoUserManager sharedUserManager]
checkLogin: [_login stringByReplacingString: @"%40"
withString: @"@"]
checkLogin: trueLogin
password: _pwd
domain: &domain
perr: &perr
+1
View File
@@ -129,6 +129,7 @@
SOGoMailDisplayFullEmail = NO;
SOGoMailDisplayRemoteInlineImages = "never";
SOGoMailCertificateEnabled = YES;
SOGoMailDisplayAttachmentAbove = NO;
SOGoMailAutoMarkAsReadDelay = "0";
SOGoMailAutoSave = "5";
+4
View File
@@ -48,6 +48,7 @@
@class NSException;
@class NSTimeZone;
@class NSURL;
@class NSUUID;
@class WOContext;
@class WORequest;
@@ -74,6 +75,9 @@
+ (NSString *) globallyUniqueObjectId;
- (NSString *) globallyUniqueObjectId;
+ (NSString *) mailUniqueMessageId;
- (NSString *) mailUniqueMessageId;
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container;
- (id) initWithName: (NSString *) _name inContainer:(id)_container;
+17 -1
View File
@@ -21,7 +21,6 @@
#import <unistd.h>
#import <NGObjWeb/SoClass.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOApplication.h>
@@ -111,11 +110,28 @@
pid, (int) f, sequence++, (int) rndm];
}
- (NSString *) globallyUniqueObjectId
{
return [[self class] globallyUniqueObjectId];
}
+ (NSString *) mailUniqueMessageId
{
/*
843F8180-4E33-7B0B-6F1B-9847CAD3E6EB
*/
return [[NSUUID UUID] UUIDString];
}
- (NSString *) mailUniqueMessageId
{
/*
843F8180-4E33-7B0B-6F1B-9847CAD3E6EB
*/
return [[self class] mailUniqueMessageId];
}
/* containment */
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container
-1
View File
@@ -66,7 +66,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer);
NSString *openIdClient;
NSString *openIdClientSecret;
NSString *openIdEmailParam;
NSString *openIdHttpVersion;
BOOL openIdEnableRefreshToken;
BOOL sendDomainInfo;
+11 -7
View File
@@ -54,7 +54,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
return total;
}
@implementation SimpleOpenIdResponse
- (id)init {
@@ -152,7 +151,7 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
- (void) initializeWithConfig: (NSDictionary *) _config
{
SOGoSystemDefaults *sd;
id refreshTokenBool, domainInfo;
id refreshTokenBool, domainInfo, intForKey;
if([_config objectForKey: @"SOGoOpenIdConfigUrl"] &&
[_config objectForKey: @"SOGoOpenIdScope"] &&
@@ -164,7 +163,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
openIdClient = [_config objectForKey: @"SOGoOpenIdClient"];
openIdClientSecret = [_config objectForKey: @"SOGoOpenIdClientSecret"];
openIdEmailParam = [_config objectForKey: @"SOGoOpenIdEmailParam"];
openIdHttpVersion = [_config objectForKey: @"SOGoOpenIdHttpVersion"];
openIdEnableRefreshToken = NO;
refreshTokenBool = [_config objectForKey: @"SOGoOpenIdEnableRefreshToken"];
@@ -176,8 +174,12 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
if (domainInfo && [domainInfo respondsToSelector: @selector (boolValue)])
sendDomainInfo = [domainInfo boolValue];
userTokenInterval = [_config objectForKey: @"SOGoOpenIdTokenCheckInterval"];
intForKey = [_config objectForKey: @"SOGoOpenIdTokenCheckInterval"];
if (intForKey && [intForKey respondsToSelector: @selector (intValue)])
userTokenInterval = [intForKey intValue];
else
userTokenInterval = 0;
[self _loadSessionFromCache: forDomain];
if(cacheUpdateNeeded)
@@ -223,7 +225,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
openIdClient = [sd openIdClient];
openIdClientSecret = [sd openIdClientSecret];
openIdEmailParam = [sd openIdEmailParam];
openIdHttpVersion = [sd openIdHttpVersion];
openIdEnableRefreshToken = [sd openIdEnableRefreshToken];
userTokenInterval = [sd openIdTokenCheckInterval];
sendDomainInfo = [sd openIdSendDomainInfo];
@@ -352,16 +353,19 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
if(SOGoOpenIDDebugEnabled)
NSLog(@"OpenId perform request: response is: %@", response);
curl_easy_cleanup(curl);
return [response autorelease];
}
else if (status == 404)
{
[self errorWithFormat: @"OpenID endpoint not found (404): %@", endpoint];
curl_easy_cleanup(curl);
return nil;
}
else
{
[self errorWithFormat: @"OpenID server internal error during %@: %@", endpoint, response];
curl_easy_cleanup(curl);
return nil;
}
}
@@ -370,7 +374,7 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
[self errorWithFormat: @"CURL error while accessing %@ (%d): %@", endpoint, rc,
[NSString stringWithCString: strlen(error) ? error : curl_easy_strerror(rc)]];
}
curl_easy_cleanup (curl);
curl_easy_cleanup(curl);
}
else
{
+2 -2
View File
@@ -790,10 +790,10 @@ static NSString *sieveScriptName = @"sogo";
imapAuthMech = nil;
if([sd doesLoginTypeByDomain])
{
r = [theUsername rangeOfString: @"@"];
r = [authname rangeOfString: @"@"];
if (r.location != NSNotFound)
{
userDomain = [theUsername substringFromIndex: r.location+1];
userDomain = [authname substringFromIndex: r.location+1];
imapAuthMech = [sd getImapAuthMechForDomain: userDomain];
}
}
-1
View File
@@ -107,7 +107,6 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
- (NSString *) openIdClient;
- (NSString *) openIdClientSecret;
- (NSString *) openIdEmailParam;
- (NSString *) openIdHttpVersion;
- (BOOL) openIdEnableRefreshToken;
- (BOOL) openIdLogoutEnabled: (NSString *) _domain;
- (int) openIdTokenCheckInterval;
-9
View File
@@ -784,15 +784,6 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return emailParam;
}
- (NSString *) openIdHttpVersion
{
NSString *httpVersion;
httpVersion = [self stringForKey: @"SOGoOpenIdHttpVersion"];
if(!httpVersion)
httpVersion = @"HTTP/1.1";
return httpVersion;
}
- (BOOL) openIdLogoutEnabled: (NSString *) _domain
{
if(_domain && [self doesLoginTypeByDomain])
+83 -76
View File
@@ -145,92 +145,91 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
realUID = nil;
domain = nil;
if ([newLogin isEqualToString: @"anonymous"]
|| [newLogin isEqualToString: @"freebusy"])
if ([newLogin isEqualToString: @"anonymous"] || [newLogin isEqualToString: @"freebusy"])
realUID = newLogin;
else
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
r = [newLogin rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
// The domain is probably appended to the username;
// make sure it is defined as a domain in the configuration.
domain = [newLogin substringFromIndex: (r.location + r.length)];
if ([[SOGoUserManager sharedUserManager] isDomainDefined: domain] &&
![sd enableDomainBasedUID])
newLogin = [newLogin substringToIndex: r.location];
r = [newLogin rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
// The domain is probably appended to the username;
// make sure it is defined as a domain in the configuration.
domain = [newLogin substringFromIndex: (r.location + r.length)];
if ([[SOGoUserManager sharedUserManager] isDomainDefined: domain] &&
![sd enableDomainBasedUID])
newLogin = [newLogin substringToIndex: r.location];
if (domain != nil && ![sd enableDomainBasedUID])
// Login domains are enabled (SOGoLoginDomains) but not
// domain-based UID (SOGoEnableDomainBasedUID).
// Drop the domain from the login name.
domain = nil;
}
}
newLogin = [newLogin stringByReplacingString: @"%40"
withString: @"@"];
if (b)
realUID = newLogin;
else
{
um = [SOGoUserManager sharedUserManager];
contactInfos = [um contactInfosForUserWithUIDorEmail: newLogin
inDomain: domain];
realUID = [contactInfos objectForKey: @"c_uid"];
if (domain == nil && [sd enableDomainBasedUID])
domain = [contactInfos objectForKey: @"c_domain"];
}
if ([realUID length] && [domain length])
{
// When the user is associated to a domain, the [SOGoUser login]
// method returns the combination login@domain while
// [SOGoUser loginInDomain] only returns the login.
r = [realUID rangeOfString: domain options: NSBackwardsSearch|NSCaseInsensitiveSearch];
// Do NOT strip @domain.com if SOGoEnableDomainBasedUID is enabled since
// the real login most likely is the email address.
if (r.location != NSNotFound && ![sd enableDomainBasedUID])
uid = [realUID substringToIndex: r.location-1];
// If we don't have the domain in the UID but SOGoEnableDomainBasedUID is
// enabled, let's add it internally so so it becomes unique across
// all potential domains.
else if (r.location == NSNotFound && [sd enableDomainBasedUID])
{
uid = [NSString stringWithString: realUID];
realUID = [NSString stringWithFormat: @"%@@%@", realUID, domain];
}
// We found the domain and SOGoEnableDomainBasedUID is enabled,
// we keep realUID.. This would happen for example if the user
// authenticates with foo@bar.com and the UIDFieldName is also foo@bar.com
else if ([sd enableDomainBasedUID])
uid = [NSString stringWithString: realUID];
}
if (domain != nil && ![sd enableDomainBasedUID])
// Login domains are enabled (SOGoLoginDomains) but not
// domain-based UID (SOGoEnableDomainBasedUID).
// Drop the domain from the login name.
domain = nil;
}
}
newLogin = [newLogin stringByReplacingString: @"%40"
withString: @"@"];
if (b)
realUID = newLogin;
else
{
um = [SOGoUserManager sharedUserManager];
contactInfos = [um contactInfosForUserWithUIDorEmail: newLogin
inDomain: domain];
realUID = [contactInfos objectForKey: @"c_uid"];
if (domain == nil && [sd enableDomainBasedUID])
domain = [contactInfos objectForKey: @"c_domain"];
}
if ([realUID length] && [domain length])
{
// When the user is associated to a domain, the [SOGoUser login]
// method returns the combination login@domain while
// [SOGoUser loginInDomain] only returns the login.
r = [realUID rangeOfString: domain options: NSBackwardsSearch|NSCaseInsensitiveSearch];
// Do NOT strip @domain.com if SOGoEnableDomainBasedUID is enabled since
// the real login most likely is the email address.
if (r.location != NSNotFound && ![sd enableDomainBasedUID])
uid = [realUID substringToIndex: r.location-1];
// If we don't have the domain in the UID but SOGoEnableDomainBasedUID is
// enabled, let's add it internally so so it becomes unique across
// all potential domains.
else if (r.location == NSNotFound && [sd enableDomainBasedUID])
{
uid = [NSString stringWithString: realUID];
realUID = [NSString stringWithFormat: @"%@@%@", realUID, domain];
}
// We found the domain and SOGoEnableDomainBasedUID is enabled,
// we keep realUID.. This would happen for example if the user
// authenticates with foo@bar.com and the UIDFieldName is also foo@bar.com
else if ([sd enableDomainBasedUID])
uid = [NSString stringWithString: realUID];
}
}
if ([realUID length])
{
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
allEmails = nil;
currentPassword = nil;
cn = nil;
ASSIGN (loginInDomain, (uid ? uid : realUID));
_defaults = nil;
_domainDefaults = nil;
_settings = nil;
mailAccounts = nil;
}
allEmails = nil;
currentPassword = nil;
cn = nil;
ASSIGN (loginInDomain, (uid ? uid : realUID));
_defaults = nil;
_domainDefaults = nil;
_settings = nil;
mailAccounts = nil;
}
}
else
{
[self release];
self = nil;
}
{
[self release];
self = nil;
}
return self;
}
@@ -265,6 +264,14 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
- (NSString *) loginInDomain
{
SOGoSystemDefaults *sd;
NSString *_domain, *realLoginInDomain;
NSRange r;
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
return self->login;
}
return loginInDomain;
}
+4 -2
View File
@@ -156,12 +156,14 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
- (void) setMailComposeFontSize: (int) newValue;
- (int) mailComposeFontSize;
- (void) setMailDisplayFullEmail: (BOOL *) newValue;
- (BOOL *) mailDisplayFullEmail;
- (void) setMailDisplayFullEmail: (BOOL) newValue;
- (BOOL) mailDisplayFullEmail;
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue;
- (NSString *) mailDisplayRemoteInlineImages;
- (void) setMailDisplayAttachmentAbove: (BOOL) newValue;
- (BOOL) mailDisplayAttachmentAbove;
- (void) setMailAutoMarkAsReadDelay: (int) newValue;
- (int) mailAutoMarkAsReadDelay;
+12 -2
View File
@@ -634,12 +634,12 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
return [self integerForKey: @"SOGoMailComposeFontSize"];
}
- (void) setMailDisplayFullEmail: (BOOL *) newValue
- (void) setMailDisplayFullEmail: (BOOL) newValue
{
[self setBool: newValue forKey: @"SOGoMailDisplayFullEmail"];
}
- (BOOL *) mailDisplayFullEmail;
- (BOOL) mailDisplayFullEmail;
{
return [self boolForKey: @"SOGoMailDisplayFullEmail"];
}
@@ -654,6 +654,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
return [self stringForKey: @"SOGoMailDisplayRemoteInlineImages"];
}
- (void) setMailDisplayAttachmentAbove: (BOOL) newValue
{
[self setBool: newValue forKey: @"SOGoMailDisplayAttachmentAbove"];
}
- (BOOL) mailDisplayAttachmentAbove;
{
return [self boolForKey: @"SOGoMailDisplayAttachmentAbove"];
}
- (void) setMailAutoMarkAsReadDelay: (int) newValue
{
[self setInteger: newValue forKey: @"SOGoMailAutoMarkAsReadDelay"];
+19 -2
View File
@@ -172,6 +172,9 @@
EOAdaptorContext *ac;
EOAdaptorChannel *fc;
NSString *profileURL, *sql, *sqlFromUserID, *sqlToUserID;
NSString *old_c_default, *old_c_settings, *new_c_default, *new_c_settings;
NSArray *attrs;
NSDictionary *row;
NSException *sqlError;
SOGoSystemDefaults *sd;
@@ -188,9 +191,22 @@
[ac beginTransaction];
sql = [NSString stringWithFormat: @"UPDATE %@ SET c_uid = '%@'"
sql = [NSString stringWithFormat: @"SELECT c_defaults, c_settings FROM %@"
@" WHERE c_uid = '%@'",
[profileLocation gcsTableName], sqlToUserID, sqlFromUserID];
[profileLocation gcsTableName], sqlFromUserID];
sqlError = [fc evaluateExpressionX: sql];
attrs = [fc describeResults: NO];
while ((row = [fc fetchAttributes: attrs withZone: NULL]))
{
old_c_default = [row objectForKey: @"c_defaults"];
old_c_settings = [row objectForKey: @"c_settings"];
new_c_default = [old_c_default stringByReplacingOccurrencesOfString:fromUserID withString:toUserID];
new_c_settings = [old_c_settings stringByReplacingOccurrencesOfString:fromUserID withString:toUserID];
}
sql = [NSString stringWithFormat: @"UPDATE %@ SET c_uid = '%@', c_defaults = '%@', "
@"c_settings = '%@' WHERE c_uid = '%@'",
[profileLocation gcsTableName], sqlToUserID, new_c_default, new_c_settings, sqlFromUserID];
sqlError = [fc evaluateExpressionX: sql];
if (sqlError)
{
@@ -568,6 +584,7 @@
[self _updateForeignSubscriptionsFromUser: oldUserID toUser: newUserID];
[self _updateLocalACLsFromUser: oldUserID toUser: newUserID];
[self _updateForeignACLsFromUser: oldUserID toUser: newUserID];
[self _updateOldUserIDDefaultAndSettings: oldUserID toUser: newUserID];
rc = YES;
}
+5 -5
View File
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "Sekundární e-mail";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum je %{0} malých znaků";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum je %{0} velkých písmen";
"POLICY_MIN_DIGIT" = "Minimum je %{0} číslic";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum je %{0} speciálních znaků";
"POLICY_MIN_LENGTH" = "Minimální délka je %{0} znaků";
+5 -5
View File
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "Dodatkowy e-mail";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Co najmniej %{0} małych liter";
"POLICY_MIN_UPPERCASE_LETTER" = "Co najmniej %{0} dużych liter";
"POLICY_MIN_DIGIT" = "Co najmniej %{0} cyfr";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Co najmniej %{0} znaków specjalnych";
"POLICY_MIN_LENGTH" = "Długość co najmniej %{0} znaków";
+18 -10
View File
@@ -78,6 +78,14 @@
NSArray *cats, *newCats, *contactCategories;
ownerLogin = [[self clientObject] ownerInContext: context];
//if ownerLogin == @"nobody", meaning the current folder is not the personnal source of the user (it's the global address book)
//No need to fetch the user "nobody". Beware that if someone is really called nobody...
if([ownerLogin isEqualToString:@"nobody"])
{
cats = [self _languageContactsCategories];
return cats;
}
ud = [[SOGoUser userWithLogin: ownerLogin] userDefaults];
cats = [ud contactsCategories];
if (!cats)
@@ -85,16 +93,16 @@
contactCategories = [card categories];
if (contactCategories)
{
newCats = [cats mergedArrayWithArray: [contactCategories trimmedComponents]];
if ([newCats count] != [cats count])
{
cats = [newCats sortedArrayUsingSelector:
@selector (localizedCaseInsensitiveCompare:)];
[ud setContactsCategories: cats];
[ud synchronize];
}
}
{
newCats = [cats mergedArrayWithArray: [contactCategories trimmedComponents]];
if ([newCats count] != [cats count])
{
cats = [newCats sortedArrayUsingSelector:
@selector (localizedCaseInsensitiveCompare:)];
[ud setContactsCategories: cats];
[ud synchronize];
}
}
return cats;
}
@@ -47,4 +47,4 @@ reply_info = "To jest odpowiedź do utworzonego przez ciebie wydarzenia";
"OK" = "OK";
"Comment" = "Komentarz";
"Description" = "Opis";
"Location" = "Location";
"Location" = "Położenie";
+14 -14
View File
@@ -171,7 +171,7 @@
/* MailListView */
"Sender" = "Odesílatel";
"Subject or Sender" = "Předmět nebo Odesílatel";
"Subject or Recipient" = "Subject or Recipient";
"Subject or Recipient" = "Předmět nebo Příjemce";
"To or Cc" = "Komu nebo Kopie";
"Entire Message" = "Celá zpráva";
"Date" = "Datum";
@@ -517,16 +517,16 @@
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
"Clean folder" = "Promazat složku";
"Clean mailbox" = "Promazat schránku";
"Delete permanently (do not use trash)" = "Smazat trvale (přeskočit Koš)";
"Apply to subfolders" = "Použít na podsložky";
"Delete e-mails older than" = "Smazat maily starší než";
"3 months" = "3 měsíce";
"6 months" = "6 měsíců";
"9 months" = "9 měsíců";
"1 year" = "1 rok";
"Custom" = "Vlastní...";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "Tǐmto navždy smažete zprávy. Chcete pokračovat?";
"Apply" = "Použít";
"%{0} message(s) deleted" = "%{0} zpráv smazáno";
+14 -14
View File
@@ -171,7 +171,7 @@
/* MailListView */
"Sender" = "Nadawca";
"Subject or Sender" = "Temat lub nadawca";
"Subject or Recipient" = "Subject or Recipient";
"Subject or Recipient" = "Nadawca lub Odbiorca";
"To or Cc" = "Do lub DW";
"Entire Message" = "Cała wiadomość";
"Date" = "Data";
@@ -517,16 +517,16 @@
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
"Clean folder" = "Uporządkuj folder";
"Clean mailbox" = "Uporządkuj skrzynkę pocztową";
"Delete permanently (do not use trash)" = "Usuń trwale (nie używaj kosza)";
"Apply to subfolders" = "Zastosuj do podfolderów";
"Delete e-mails older than" = "Usuń wiadomości starsze niż";
"3 months" = "3 miesiące";
"6 months" = "6 miesięcy";
"9 months" = "9 miesięcy";
"1 year" = "1 rok";
"Custom" = "Ustaw";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "Za chwilę trwale usuniesz część wiadomości. Na pewno chcesz to zrobić?";
"Apply" = "Wykonaj";
"%{0} message(s) deleted" = "usunięto %{0} wiadomości";
@@ -107,8 +107,11 @@
"Unhandled error response" = "خطأ استجابة غير معالجة";
"Password change is not supported." = "لا يتم اعتماد تغيير كلمة المرور.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "كلمة مرور جديدة";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "تأكيد";
"Change" = "Change";
"Cancel" = "إلغاء";
"Please wait..." = "يرجى الانتظار ...";
"Close" = "Close";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Landu gabeko errore erantzuna";
"Password change is not supported." = "Pasahitz aldaketa ez dago onartua.";
"Unhandled HTTP error code: %{0}" = "Landu gabeko HTTP errore kodea: %{0}";
"Current password" = "Current password";
"New password" = "New password";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Berrespena";
"Change" = "Change";
"Cancel" = "Ezeztatu";
"Please wait..." = "Itxaron mesedez...";
"Close" = "Close";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Nepoznata greška";
"Password change is not supported." = "Promjena šifre nije podržana.";
"Unhandled HTTP error code: %{0}" = "Neobrađena greška HTTP kod: %{0}";
"Current password" = "Current password";
"New password" = "Nova šifra";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potvrda";
"Change" = "Change";
"Cancel" = "Otkazati";
"Please wait..." = "Molimo sačekajte...";
"Close" = "Zatvoriti";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Erro de resposta não tratado";
"Password change is not supported." = "Alteração da senha não suportada.";
"Unhandled HTTP error code: %{0}" = "Erro HTTP não tratado: %{0}";
"Current password" = "Current password";
"New password" = "Nova senha";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmação";
"Change" = "Change";
"Cancel" = "Cancelar";
"Please wait..." = "Por favor, aguarde...";
"Close" = "Fechar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Необработена грешка отговор";
"Password change is not supported." = "Промяна на парола не се поддържа.";
"Unhandled HTTP error code: %{0}" = "Необработена HTTP грешка с код: %{0}";
"Current password" = "Current password";
"New password" = "Нова парола";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Потвърждение";
"Change" = "Change";
"Cancel" = "Отказ";
"Please wait..." = "Моля изчакайте ...";
"Close" = "Затваряне";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Error no previst";
"Password change is not supported." = "No s'admet canvi de contrasenyes.";
"Unhandled HTTP error code: %{0}" = "Error HTTP no previst. Codi: %{0}";
"Current password" = "Current password";
"New password" = "Contrasenya nova";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmació";
"Change" = "Change";
"Cancel" = "Cancel·lar";
"Please wait..." = "Si us plau, espereu-vos...";
"Close" = "Tancar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "返回未知错误";
"Password change is not supported." = "不支持修改密码";
"Unhandled HTTP error code: %{0}" = "未知 HTTP 错误: %{0}";
"Current password" = "Current password";
"New password" = "新密码";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "确认";
"Change" = "Change";
"Cancel" = "取消";
"Please wait..." = "请稍候…";
"Close" = "关闭";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Password change is not supported.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "New password";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmation";
"Change" = "Change";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Close" = "Close";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Promjena lozinke nije podržana.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "Nova lozinka";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potvrdi";
"Change" = "Change";
"Cancel" = "Odustani";
"Please wait..." = "Molimo pričekajte...";
"Close" = "Zatvori";
+4 -1
View File
@@ -86,7 +86,7 @@
"Change your Password" = "Změňte své heslo";
"The password was changed successfully." = "Heslo bylo úspěšně změněno.";
"Your password has expired, please enter a new one below" = "Vaše heslo expirovalo, prosím zadejte nové";
"Your password is too weak. Please choose a stronger password to enhance your security" = "Your password is too weak. Please choose a stronger password to enhance your security";
"Your password is too weak. Please choose a stronger password to enhance your security" = "Heslo je příliš slabé. Zvolte raději silnější heslo";
"Password must not be empty." = "Heslo nesmí být prázdné.";
"The passwords do not match. Please try again." = "Hesla se neshodují. Prosím zadejte znovu.";
"Password Grace Period" = "Doba platnosti hesla";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neošetřená chyba";
"Password change is not supported." = "Změna hesla není podporována.";
"Unhandled HTTP error code: %{0}" = "Neošetřený HTTP chybový kód: %{0}";
"Current password" = "Stávající heslo";
"New password" = "Nové heslo";
"Passwords don't match" = "Hesla se neshodují";
"Confirmation" = "Potvrzení";
"Change" = "Změnit";
"Cancel" = "Storno";
"Please wait..." = "Prosím čekejte...";
"Close" = "Zavřít";
@@ -107,8 +107,11 @@
"Unhandled error response" = "fejlreaktion";
"Password change is not supported." = "Ændring af adgangskoden er ikke understøttet.";
"Unhandled HTTP error code: %{0}" = "HTTP fejlkode: %{0}";
"Current password" = "Nuværende adgangskode";
"New password" = "Ny adgangskode";
"Passwords don't match" = "Adgangskoder stemmer ikke overens";
"Confirmation" = "Bekræftelse";
"Change" = "Skift";
"Cancel" = "Annullér";
"Please wait..." = "Vent venligst ...";
"Close" = "Luk";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Onverwerkte foutmelding";
"Password change is not supported." = "Wachtwoordwijziging wordt niet ondersteund.";
"Unhandled HTTP error code: %{0}" = "Onverwerkte HTTP-foutcode: %{0}";
"Current password" = "Current password";
"New password" = "Nieuw wachtwoord";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Bevestiging";
"Change" = "Change";
"Cancel" = "Annuleren";
"Please wait..." = "Een ogenblik geduld ...";
"Close" = "Sluiten";
@@ -110,8 +110,11 @@ See <a href=\"http://www.sogo.nu/en/support/community.html\">this page</a> for v
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Password change is not supported.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "New password";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmation";
"Change" = "Change";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Close" = "Close";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Käsittelemätön virhe";
"Password change is not supported." = "Salasanan vaihto ei ole tuettu.";
"Unhandled HTTP error code: %{0}" = "Käsittelemätön HTTP virhe: %{0}";
"Current password" = "Current password";
"New password" = "Uusi salasana";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Vahvistus";
"Change" = "Change";
"Cancel" = "Peruuta";
"Please wait..." = "Odota hetki...";
"Close" = "Sulje";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Erreur inconnue";
"Password change is not supported." = "Changement de mot de passe non-supporté.";
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
"Current password" = "Mot de passe actuel";
"New password" = "Nouveau mot de passe";
"Passwords don't match" = "Les mots de passe ne correspondent pas";
"Confirmation" = "Confirmation";
"Change" = "Changer";
"Cancel" = "Annuler";
"Please wait..." = "Veuillez patienter...";
"Close" = "Fermer";
@@ -107,8 +107,11 @@
"Unhandled error response" = "erro de resposta desatendido";
"Password change is not supported." = "Cambio de contrasinal non soportado.";
"Unhandled HTTP error code: %{0}" = "Código de Erro HTTP desatendido: %{0}";
"Current password" = "Current password";
"New password" = "Novo contrasinal";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmación";
"Change" = "Change";
"Cancel" = "Cancelar";
"Please wait..." = "Por favor, agarde...";
"Close" = "Pechar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unbehandelte Fehlerantwort";
"Password change is not supported." = "Passwortänderung wird nicht unterstützt.";
"Unhandled HTTP error code: %{0}" = "Unbehandelter HTTP-Fehlercode: %{0}";
"Current password" = "Aktuelles Passwort";
"New password" = "Neues Passwort";
"Passwords don't match" = "Die Passwörter stimmen nicht überein";
"Confirmation" = "Bestätigung";
"Change" = "Ändern";
"Cancel" = "Abbrechen";
"Please wait..." = "Bitte warten...";
"Close" = "Schließen";
@@ -107,8 +107,11 @@
"Unhandled error response" = "תגובת שגיאה לא מטופלת";
"Password change is not supported." = "שינוי סיסמה אינו נתמך.";
"Unhandled HTTP error code: %{0}" = "שגיאת HTTP לא מטופלת מספר: {0}%";
"Current password" = "Current password";
"New password" = "סיסמה חדשה";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "אישור";
"Change" = "Change";
"Cancel" = "ביטול";
"Please wait..." = "אנא המתן...";
"Close" = "סגירה";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Nem kezelt hiba";
"Password change is not supported." = "A jelszó megváltoztatása nem támogatott.";
"Unhandled HTTP error code: %{0}" = "Nem kezelt HTTP hibakód: /{0}";
"Current password" = "Current password";
"New password" = "Új jelszó";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Megerősítés";
"Change" = "Change";
"Cancel" = "Törlés";
"Please wait..." = "Kérem várjon ...";
"Close" = "Bezárás";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Ekki er hægt að breyta lykilorði í póstkerfinu. Notið Ugluna.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "Nýtt lykilorð";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Staðfesting";
"Change" = "Change";
"Cancel" = "Hætta við";
"Please wait..." = "Augnablik...";
"Close" = "Close";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Respon kesalahan tak tertangani";
"Password change is not supported." = "Perubahan katasandi tidak didukung";
"Unhandled HTTP error code: %{0}" = "kode error HTTP tidak tertangani: %{0}";
"Current password" = "Current password";
"New password" = "Katasandi baru";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Konfirmasi";
"Change" = "Change";
"Cancel" = "Batal";
"Please wait..." = "Silahkan Tunggu";
"Close" = "Tutup";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Risposta con errore non gestito";
"Password change is not supported." = "Cambio di password non supportato.";
"Unhandled HTTP error code: %{0}" = "Codice errore HTTP non gestito: %{0}";
"Current password" = "Current password";
"New password" = "Nuova password";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Conferma";
"Change" = "Change";
"Cancel" = "Cancella";
"Please wait..." = "Prego attendere...";
"Close" = "Chiudi";
@@ -107,8 +107,11 @@
"Unhandled error response" = "処理できないエラーの応答";
"Password change is not supported." = "パスワードの変更をサポートしていません。";
"Unhandled HTTP error code: %{0}" = "処理できないHTTPのエラーコード: %{0}";
"Current password" = "Current password";
"New password" = "新しいパスワード";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "パスワードの再入力";
"Change" = "Change";
"Cancel" = "キャンセル";
"Please wait..." = "しばらくお待ちください...";
"Close" = "閉じる";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Парольді өзгерту қолданылмайды.";
"Unhandled HTTP error code: %{0}" = "Өңделмеген қателер HTTP-код: %{0}";
"Current password" = "Current password";
"New password" = "Жаңа пароль";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Растау";
"Change" = "Change";
"Cancel" = "Кері қарай";
"Please wait..." = "Күте тұрыңыз...";
"Close" = "Жабу";
@@ -107,8 +107,11 @@
"Unhandled error response" = "처리되지 않은 오류 응답";
"Password change is not supported." = "비밀번호 변경이 지원되지 않습니다.";
"Unhandled HTTP error code: %{0}" = "처리되지 않은 HTTP 오류 코드: %{0}";
"Current password" = "Current password";
"New password" = "새 비밀번호";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "확인";
"Change" = "Change";
"Cancel" = "취소";
"Please wait..." = "기다려 주십시오...";
"Close" = "닫기";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neapstrādāta kļūda";
"Password change is not supported." = "Paroles maiņa nav atbalstīta.";
"Unhandled HTTP error code: %{0}" = "Neparedzēts HTTP kļūdas kods: %{0}";
"Current password" = "Current password";
"New password" = "Jauna parole";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Apstiprinājums";
"Change" = "Change";
"Cancel" = "Atcelt";
"Please wait..." = "Lūdzu, uzgaidiet...";
"Close" = "Aizvērt";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neapdorotas klaidos atsakas";
"Password change is not supported." = "Slaptažodžio keitimas nepalaikomas.";
"Unhandled HTTP error code: %{0}" = "Neapdorotas HTTP klaidos kodas: %{0}";
"Current password" = "Current password";
"New password" = "Naujas slaptažodis";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Patvirtinimas";
"Change" = "Change";
"Cancel" = "Atšaukti";
"Please wait..." = "Prašome palaukti...";
"Close" = "Uždaryti";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Непозната грешка";
"Password change is not supported." = "Промената на лозинката не е подржана.";
"Unhandled HTTP error code: %{0}" = "Непозната HTTP грешка: %{0}";
"Current password" = "Current password";
"New password" = "Нова лозинка";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Потврда";
"Change" = "Change";
"Cancel" = "Откажи";
"Please wait..." = "Ве молиме почекајте...";
"Close" = "Затвори";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neobrađeni odziv greške";
"Password change is not supported." = "Promjena lozinke nije podržana.";
"Unhandled HTTP error code: %{0}" = "Neobrađena greška HTTP koda: %{0}";
"Current password" = "Current password";
"New password" = "Nova lozinka";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potvrda";
"Change" = "Change";
"Cancel" = "Otkaži";
"Please wait..." = "Molimo sačekajte...";
"Close" = "Zatvori";
@@ -53,7 +53,7 @@
"Indonesian" = "bahasa Indonesia";
"Italian" = "Italiano";
"Japanese" = "日本語";
"Korean" = "한국어";
"Korean" = "Koreansk";
"Kazakh" = "Қазақ";
"Latvian" = "Latviešu";
"Lithuanian" = "Lietuvių";
@@ -73,7 +73,7 @@
"SpanishSpain" = "Español (España)";
"SpanishArgentina" = "Español (Argentina)";
"Swedish" = "Svenska";
"Thai" = "ภาษา";
"Thai" = "Thailandsk";
"TurkishTurkey" = "Türkçe (Türkiye)";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Uhåndtert feilmelding.";
"Password change is not supported." = "Passordendring er ikke støttet.";
"Unhandled HTTP error code: %{0}" = "Uhåndtert HTTP-feilkode: %{0}";
"Current password" = "Nåværende passord";
"New password" = "Nytt passord";
"Passwords don't match" = "Passordene er ikke like";
"Confirmation" = "Bekreftelse";
"Change" = "Endre";
"Cancel" = "Avbryt";
"Please wait..." = "Vennligst vent...";
"Close" = "Lukk";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Password change is not supported.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Current password" = "Current password";
"New password" = "Nytt passord";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Bekreftelse";
"Change" = "Change";
"Cancel" = "Avbryt";
"Please wait..." = "Vennligst vent...";
"Close" = "Close";
+4 -1
View File
@@ -86,7 +86,7 @@
"Change your Password" = "Zmień swoje hasło";
"The password was changed successfully." = "Hasło zostało zmienione.";
"Your password has expired, please enter a new one below" = "Ważność twojego hasła wygasła, wprowadź niżej nowe hasło";
"Your password is too weak. Please choose a stronger password to enhance your security" = "Your password is too weak. Please choose a stronger password to enhance your security";
"Your password is too weak. Please choose a stronger password to enhance your security" = "Twoje hasło jest za słabe. Wybierz silniejsze hasło, by poprawić bezpieczeństwo.";
"Password must not be empty." = "Hasło nie może być puste.";
"The passwords do not match. Please try again." = "Hasła nie są zgodne. Spróbuj jeszcze raz.";
"Password Grace Period" = "Okres pobłażliwości hasła";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Niezidentyfikowany błąd";
"Password change is not supported." = "Zmiana hasła nie jest obsługiwana.";
"Unhandled HTTP error code: %{0}" = "Nieobsługiwany kod błędu HTTP: %{0}";
"Current password" = "Aktualne hasło";
"New password" = "Nowe hasło";
"Passwords don't match" = "Hasła nie są takie same";
"Confirmation" = "Potwierdzenie";
"Change" = "Zmień";
"Cancel" = "Anuluj";
"Please wait..." = "Zaczekaj proszę...";
"Close" = "Zamknij";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Erro de resposta não tratado";
"Password change is not supported." = "Alteração da palavra-passe não é suportada.";
"Unhandled HTTP error code: %{0}" = "Erro HTTP não tratado: %{0}";
"Current password" = "Current password";
"New password" = "Nova palavra-passe";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmação";
"Change" = "Change";
"Cancel" = "Cancelar";
"Please wait..." = "Por favor aguarde...";
"Close" = "Fechar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Răspuns de eroare nedeclarat";
"Password change is not supported." = "Schimbare parolei nu este suportată.";
"Unhandled HTTP error code: %{0}" = "Răspuns de eroare HTTP nedeclarat: %{0}";
"Current password" = "Current password";
"New password" = "Parola nouă";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmare";
"Change" = "Change";
"Cancel" = "Renunţare";
"Please wait..." = "Vă rugăm să așteptați...";
"Close" = "Închide";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Необработанный ответ об ошибке";
"Password change is not supported." = "Смена пароля не поддерживается.";
"Unhandled HTTP error code: %{0}" = "Необработанные ошибки HTTP-код:% {0}";
"Current password" = "Current password";
"New password" = "Новый пароль";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Подтверждение";
"Change" = "Change";
"Cancel" = "Отменить";
"Please wait..." = "Пожалуйста, подождите...";
"Close" = "Закрыть";
+7 -4
View File
@@ -274,7 +274,7 @@ static const NSString *kJwtKey = @"jwt";
SOGoPasswordPolicyError err;
int expire, grace;
BOOL rememberLogin, b;
BOOL rememberLogin, b, loginSuccess;
err = PolicyNoError;
expire = grace = -1;
@@ -296,12 +296,14 @@ static const NSString *kJwtKey = @"jwt";
perr: &err expire: &expire grace: &grace additionalInfo: &additionalLoginInformations useCache: NO];
[self translateAdditionalLoginInformations: &additionalLoginInformations];
if (b
loginSuccess = b
&& (err == PolicyNoError)
// no password policy
&& ((expire < 0 && grace < 0) // no password policy or everything is alright
|| (expire < 0 && grace > 0) // password expired, grace still permits login
|| (expire >= 0 && grace == -1))) // password about to expire OR ppolicy activated and passwd never changed
|| (expire >= 0 && grace == -1)); // password about to expire OR ppolicy activated and passwd never changed
if (loginSuccess)
{
NSMutableDictionary *json = [NSMutableDictionary dictionary];
@@ -442,7 +444,8 @@ static const NSString *kJwtKey = @"jwt";
response = [self _responseWithLDAPPolicyError: err additionalInfos: additionalLoginInformations];
}
if (rememberLogin)
//Only remember login If the auth was succesful...
if (rememberLogin && loginSuccess)
[response addCookie: [self _cookieWithUsername: [params objectForKey: @"userName"]]];
else
[response addCookie: [self _cookieWithUsername: nil]];
@@ -107,8 +107,11 @@
"Unhandled error response" = "Необрађени одзив грешке";
"Password change is not supported." = "Промена лозинке није подржана.";
"Unhandled HTTP error code: %{0}" = "Необрађена грешка ХТТП кода: %{0}";
"Current password" = "Current password";
"New password" = "Нова лозинка";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Потврда";
"Change" = "Change";
"Cancel" = "Откажи";
"Please wait..." = "Молимо сачекајте...";
"Close" = "Затвори";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neobrađeni odziv greške";
"Password change is not supported." = "Promena lozinke nije podržana.";
"Unhandled HTTP error code: %{0}" = "Neobrađena greška HTTP koda: %{0}";
"Current password" = "Current password";
"New password" = "Nova lozinka";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potvrda";
"Change" = "Change";
"Cancel" = "Otkaži";
"Please wait..." = "Molimo sačekajte...";
"Close" = "Zatvori";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Nespracované chyby na odpoveď";
"Password change is not supported." = "Zmena hesla nie je povolená.";
"Unhandled HTTP error code: %{0}" = "Nespracované HTTP. Kód chyby:% {0}";
"Current password" = "Current password";
"New password" = "Nové heslo";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potvrdiť";
"Change" = "Change";
"Cancel" = "Zrušiť";
"Please wait..." = "Prosím, čakajte ...";
"Close" = "Zavrieť";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Neobravnavana napaka odziva";
"Password change is not supported." = "Sprememba gesla ni podprta.";
"Unhandled HTTP error code: %{0}" = "Neobravnavana HTTP napaka: %{0}";
"Current password" = "Current password";
"New password" = "Novo geslo";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Potrditev";
"Change" = "Change";
"Cancel" = "Prekini";
"Please wait..." = "Prosim počakaj...";
"Close" = "Zapri";
@@ -107,8 +107,11 @@
"Unhandled error response" = "error de respuesta desatendido";
"Password change is not supported." = "El cambio de contraseña no está soportado.";
"Unhandled HTTP error code: %{0}" = "Codigo de Error HTTP desatendido: %{0}";
"Current password" = "Current password";
"New password" = "Nueva contraseña";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmación";
"Change" = "Change";
"Cancel" = "Cancelar";
"Please wait..." = "Por favor, espere...";
"Close" = "Cerrar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "error de respuesta desatendido";
"Password change is not supported." = "Cambio de contraseña no soportado.";
"Unhandled HTTP error code: %{0}" = "Codigo de Error HTTP desatendido: %{0}";
"Current password" = "Current password";
"New password" = "Nueva contraseña";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Confirmación";
"Change" = "Change";
"Cancel" = "Cancelar";
"Please wait..." = "Por favor, espere...";
"Close" = "Cerrar";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Ohanterat fel har inträffat";
"Password change is not supported." = "Stöd saknas för ändring av lösenord.";
"Unhandled HTTP error code: %{0}" = "Ohanterat HTTP felkod: %{0}";
"Current password" = "Current password";
"New password" = "Nytt lösenord";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Bekräfta";
"Change" = "Change";
"Cancel" = "Avbryt";
"Please wait..." = "Var god vänta...";
"Close" = "Close";
+3
View File
@@ -107,8 +107,11 @@
"Unhandled error response" = "การตอบสนองข้อผิดพลาดที่ไม่สามารถจัดการได้";
"Password change is not supported." = "ไม่รองรับการเปลี่ยนรหัสผ่าน";
"Unhandled HTTP error code: %{0}" = "โค้ดข้อผิดพลาด HTTP ไม่ได้รับการจัดการ: %{0}";
"Current password" = "Current password";
"New password" = "รหัสผ่านใหม่";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "ยืนยัน";
"Change" = "Change";
"Cancel" = "ยกเลิก";
"Please wait..." = " กรุณารอสักครู่...";
"Close" = "ปิด";
@@ -107,8 +107,11 @@
"Unhandled error response" = "İşlenmedi hatası yanıtı";
"Password change is not supported." = "Parolanın değiştirilmesi desteklenmiyor.";
"Unhandled HTTP error code: %{0}" = "İşlenmedi HTTP hata kodu: %{0}";
"Current password" = "Current password";
"New password" = "Yeni parola";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Onay";
"Change" = "Change";
"Cancel" = "İptal";
"Please wait..." = "Lütfen bekleyin...";
"Close" = "Kapat";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Невизначений результат помилки";
"Password change is not supported." = "Функція зміни пароля не підтримується.";
"Unhandled HTTP error code: %{0}" = "Невизначений код помилкий HTTP: %{0}";
"Current password" = "Current password";
"New password" = "Новий пароль";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Підтвердження";
"Change" = "Change";
"Cancel" = "Скасувати";
"Please wait..." = "Будь ласка, зачекайте...";
"Close" = "Закрити";
@@ -107,8 +107,11 @@
"Unhandled error response" = "Ymateb gwall heb fodd ei drin";
"Password change is not supported." = "Dim cefnogaeth i newid cyfrinair.";
"Unhandled HTTP error code: %{0}" = "Cod gwall HTTP heb fodd ei drin: %{0}";
"Current password" = "Current password";
"New password" = "Cyfrinair newydd";
"Passwords don't match" = "Passwords don't match";
"Confirmation" = "Cadarnhad";
"Change" = "Change";
"Cancel" = "Canslo";
"Please wait..." = "Arhoswch...";
"Close" = "Cau";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Default font size";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Default font size";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Standardna veličina fonta";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Inserir assinatura ao encaminhar";
"Show recipients or sender full email in mailboxes" = "Mostrar destinatários ou remetente do email completo nas caixas de correio";
"Hide attachements for inline images" = "Ocultar anexos de imagens embutidas";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Tamanho de fonte padrão";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Размер на шрифта по подразбиране";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Mida per defecte del tipus de lletra";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "默认字体大小";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Default font size";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Zadana veličina slova";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Vkládat podpis do přeposlaných zpráv";
"Show recipients or sender full email in mailboxes" = "Zobrazovat kompletní e-mailové adresy v poštovních složkách";
"Hide attachements for inline images" = "Skrývat obrázky v textu";
"Show attachments above the message" = "Zobrazit přílohy nad zprávou";
/* Base font size for messages composed in HTML */
"Default font size" = "Výchozí velikost písma";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Indsæt signatur på videresend";
"Show recipients or sender full email in mailboxes" = "Vis modtagere eller afsender fulde e-mail i postkasserne";
"Hide attachements for inline images" = "Skjul vedhæftet filer for indsatte billeder";
"Show attachments above the message" = "Vis vedhæftede filer over beskeden";
/* Base font size for messages composed in HTML */
"Default font size" = "Standard skriftstørrelse";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Handtekening bij doorsturen invoegen";
"Show recipients or sender full email in mailboxes" = "Toon ontvangers of afzenders volledige e-mail in mailboxen";
"Hide attachements for inline images" = "Bijlagen voor inline-afbeeldingen verbergen";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Standaard lettergrootte";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Default font size";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insert signature on forward";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
/* Base font size for messages composed in HTML */
"Default font size" = "Oletuskirjasinkoko";
@@ -207,6 +207,7 @@
"Insert signature on forward" = "Insérer la signature sur un transfert";
"Show recipients or sender full email in mailboxes" = "Afficher l'email complet du destinataire ou expéditeur dans les boîtes aux lettres";
"Hide attachements for inline images" = "Cacher les pièces jointes pour les images 'inline'";
"Show attachments above the message" = "Montrer les pièces jointes au dessus du message";
/* Base font size for messages composed in HTML */
"Default font size" = "Taille de la police par défaut";
Loaded 100 of 164 files, more files were not shown because too many files have changed in this diff. Show more