mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-22 02:58:11 +00:00
Merge branch 'master' into feature-gdpr
This commit is contained in:
commit
d505b874f7
379 files changed
+2817
-1217
No files matched your search
@@ -53,7 +53,7 @@ vtodo_class2 = "(Vertrauliche Aufgabe)";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "Folgendes wurde am Termin \"%{Summary}\" geändert:";
|
||||
"Please accept or decline those changes."
|
||||
= "Bitte akzeptieren Sie diese Änderung, oder lehnen Sie diese ab.";
|
||||
= "Bitte akzeptieren Sie diese Änderungen, oder lehnen Sie diese ab.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Einladung zugestimmt: \"%{Summary}\"";
|
||||
|
||||
@@ -12,9 +12,9 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"The event \"%{Summary}\" was created" = "Įvykis \"%{summary}\" buvo sukurtas";
|
||||
"The event \"%{Summary}\" was deleted" = "Įvykis \"%{Summary}\" buvo ištrintas";
|
||||
"The event \"%{Summary}\" was updated" = "Įvykis \"%{Summary}\" buvo atnaujintas";
|
||||
"The task \"%{Summary}\" was created" = "Įvykis \\"%{summary}\\" buvo sukurtas";
|
||||
"The task \"%{Summary}\" was deleted" = "Įvykis \\"%{Summary}\\" buvo ištrintas";
|
||||
"The task \"%{Summary}\" was updated" = "Įvykis \\"%{Summary}\\" buvo atnaujintas";
|
||||
"The task \"%{Summary}\" was created" = "Įvykis \"%{summary}\" buvo sukurtas";
|
||||
"The task \"%{Summary}\" was deleted" = "Įvykis \"%{Summary}\" buvo ištrintas";
|
||||
"The task \"%{Summary}\" was updated" = "Įvykis \"%{Summary}\" buvo atnaujintas";
|
||||
"The following attendees(s) were notified" = "Šiems dalyviui(iams) buvo pranešta";
|
||||
"The following attendees(s) were added" = "Šie dalyvis(iai) buvo pridėti";
|
||||
"The following attendees(s) were removed" = "Šie dalyvis(iai) buvo pašalinti";
|
||||
@@ -33,13 +33,13 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"attendee_label" = "Dalyvis";
|
||||
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Įvykio pakvietimas: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(išsiųsta nuo %{SentBy}) ";
|
||||
"Event Invitation: \"%{Summary}\"" = "Kvietimas į renginį: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(išsiųsta %{SentBy}) ";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} pakvietė Jus į %{Summary}.\nPradžia: %{StartDate}\nPabaiga: %{EndDate}\nAprašymas: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} pakvietė Jus į %{Summary}.\n\nPradžia: %{StartDate} nuo %{StartTime}\nPabaiga: %{EndDate} nuo %{EndTime}\nAprašymas: %{Description}";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Įvykis atšauktas: \\"%{Summary}\\"";
|
||||
"Event Cancelled: \"%{Summary}\"" = "Įvykis atšauktas: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText} atšaukė šį įvykį: %{Summary}.\n\nPradžia: %{StartDate}\nPabaiga: %{EndDate}\nAprašymas: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
@@ -63,11 +63,11 @@ vtodo_class2 = "(Konfidenciali užduotis)";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText} priėmė Jūsų įvykio pakvietimą.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText} atmetė Jūsų įvykio pakvietimą.";
|
||||
= "%{Attendee} %{SentByText} atmetė Jūsų pakvietimą į renginį.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText} delegavo pakvietimą į %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText} neapsisprendė dėl Jūsų įvykio pakvietimo.";
|
||||
= "%{Attendee} %{SentByText} neapsisprendė dėl Jūsų kvietimo į renginį.";
|
||||
|
||||
/* Reminder */
|
||||
"Reminder: \"%{Summary}\" - %{StartDate}" = "Priminimas: \"%{Summary}\" - %{StartDate}";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
"Personal Address Book" = "Asmeninė adresų knyga";
|
||||
"Collected Address Book" = "Rinktinė adresų knyga";
|
||||
"Collected Address Book" = "Rinktinė adresų knygą";
|
||||
@@ -418,7 +418,7 @@ convention:
|
||||
[self setCategories: [o componentsSeparatedByString: @","]];
|
||||
|
||||
// Photo
|
||||
if ([ldifRecord objectForKey: @"photo"])
|
||||
if ([ldifRecord objectForKey: @"photo"] && [ldifRecord objectForKey: @"photo"] != [NSNull null])
|
||||
[self setPhoto: [[ldifRecord objectForKey: @"photo"] stringByEncodingBase64]];
|
||||
|
||||
[self cleanupEmptyChildren];
|
||||
|
||||
@@ -271,6 +271,9 @@ static NSArray *folderListingFields = nil;
|
||||
if ([data length])
|
||||
[contactRecord setObject: data forKey: @"id"];
|
||||
|
||||
// Container name
|
||||
[contactRecord setObject: [self displayName] forKey: @"containerName"];
|
||||
|
||||
// c_cn
|
||||
data = [contactRecord objectForKey: @"c_cn"];
|
||||
if (![data length])
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
//source id
|
||||
[newRecord setObject: [source sourceID] forKey: @"sourceID"];
|
||||
|
||||
//source display name
|
||||
[newRecord setObject: [self displayName]
|
||||
forKey: @"containerName"];
|
||||
|
||||
// c_name => id
|
||||
[newRecord setObject: [oldRecord objectForKey: @"c_name"]
|
||||
forKey: @"c_name"];
|
||||
@@ -430,26 +434,43 @@
|
||||
{
|
||||
NSArray *records, *result;
|
||||
EOSortOrdering *ordering;
|
||||
BOOL processed;
|
||||
|
||||
result = nil;
|
||||
processed = NO;
|
||||
|
||||
if ([filter length] > 0 || ![source listRequiresDot])
|
||||
[source setListRequiresDot: NO];
|
||||
if ( ![source listRequiresDot])
|
||||
{
|
||||
records = [source fetchContactsMatching: filter
|
||||
if ([filter length] > 0) {
|
||||
records = [source fetchContactsMatching: filter
|
||||
withCriteria: criteria
|
||||
inDomain: domain];
|
||||
[childRecords setObjects: records
|
||||
forKeys: [records objectsForKey: @"c_name"
|
||||
notFoundMarker: nil]];
|
||||
records = [self _flattenedRecords: records];
|
||||
ordering
|
||||
= [EOSortOrdering sortOrderingWithKey: sortKey
|
||||
selector: ((sortOrdering == NSOrderedDescending)
|
||||
? EOCompareCaseInsensitiveDescending
|
||||
: EOCompareCaseInsensitiveAscending)];
|
||||
result
|
||||
= [records sortedArrayUsingKeyOrderArray:
|
||||
[NSArray arrayWithObject: ordering]];
|
||||
processed = YES;
|
||||
} else if ([[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesEnabled]) {
|
||||
records = [source fetchContactsMatching: filter
|
||||
withCriteria: criteria
|
||||
inDomain: domain
|
||||
limit: [[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesCount]];
|
||||
processed = YES;
|
||||
}
|
||||
|
||||
if (processed) {
|
||||
[childRecords setObjects: records
|
||||
forKeys: [records objectsForKey: @"c_name"
|
||||
notFoundMarker: nil]];
|
||||
records = [self _flattenedRecords: records];
|
||||
ordering
|
||||
= [EOSortOrdering sortOrderingWithKey: sortKey
|
||||
selector: ((sortOrdering == NSOrderedDescending)
|
||||
? EOCompareCaseInsensitiveDescending
|
||||
: EOCompareCaseInsensitiveAscending)];
|
||||
result
|
||||
= [records sortedArrayUsingKeyOrderArray:
|
||||
[NSArray arrayWithObject: ordering]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
BOOL isHTML;
|
||||
BOOL sign;
|
||||
BOOL encrypt;
|
||||
NSMutableArray *tmpFiles;
|
||||
|
||||
// Used during S/MIME encryption
|
||||
NSMutableDictionary *certificates;
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#import <SOGo/SOGoUserFolder.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/NGMimeFileData+SOGo.h>
|
||||
|
||||
#import <NGCards/NGVCard.h>
|
||||
|
||||
@@ -142,6 +143,7 @@ static NSString *userAgent = nil;
|
||||
isHTML = NO;
|
||||
sign = NO;
|
||||
encrypt = NO;
|
||||
tmpFiles = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -157,6 +159,7 @@ static NSString *userAgent = nil;
|
||||
[sourceFlag release];
|
||||
[inReplyTo release];
|
||||
[references release];
|
||||
[tmpFiles release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -932,7 +935,6 @@ static NSString *userAgent = nil;
|
||||
if (filename)
|
||||
{
|
||||
NSMutableDictionary *currentInfo;
|
||||
|
||||
currentInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
filename, @"filename",
|
||||
mimeType, @"mimetype",
|
||||
@@ -1922,8 +1924,10 @@ static NSString *userAgent = nil;
|
||||
if (_extractImages)
|
||||
{
|
||||
newText = [text htmlByExtractingImages: extractedBodyParts];
|
||||
if ([extractedBodyParts count])
|
||||
if ([extractedBodyParts count]) {
|
||||
[self setText: newText];
|
||||
[self addTmpFiles: extractedBodyParts];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1935,8 +1939,11 @@ static NSString *userAgent = nil;
|
||||
//[self debugWithFormat: @"MIME Envelope: %@", map];
|
||||
allBodyParts = [self bodyPartsForAllAttachments];
|
||||
|
||||
if (!allBodyParts)
|
||||
return nil;
|
||||
if (!allBodyParts) {
|
||||
return nil;
|
||||
} else {
|
||||
[self addTmpFiles: allBodyParts];
|
||||
}
|
||||
|
||||
//[self debugWithFormat: @"attachments: %@", bodyParts];
|
||||
|
||||
@@ -1955,53 +1962,8 @@ static NSString *userAgent = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (_extractImages)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < [extractedBodyParts count] ; i++) {
|
||||
NSMutableDictionary *currentInfo;
|
||||
NSString *filename, *mimeType, *bodyId, *encoding;
|
||||
NSData *body;
|
||||
NGMimeBodyPart *extractedBodyPart;
|
||||
NGMimeContentDispositionHeaderField *contentDisposition;
|
||||
|
||||
extractedBodyPart = [extractedBodyParts objectAtIndex:i];
|
||||
if (extractedBodyPart && [extractedBodyPart headerForKey: @"content-disposition"]) {
|
||||
encoding = [extractedBodyPart encoding];
|
||||
contentDisposition = [[NGMimeContentDispositionHeaderField alloc] initWithString: [extractedBodyPart headerForKey: @"content-disposition"]];
|
||||
|
||||
if (encoding
|
||||
&& [extractedBodyPart contentType]
|
||||
&& [extractedBodyPart contentId]
|
||||
&& [contentDisposition filename]) {
|
||||
|
||||
mimeType = [[extractedBodyPart contentType] stringValue];
|
||||
bodyId = [[extractedBodyPart contentId] stringValue];
|
||||
filename = [contentDisposition filename];
|
||||
currentInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
filename, @"filename",
|
||||
mimeType, @"mimetype",
|
||||
bodyId, @"bodyId",
|
||||
nil];
|
||||
|
||||
if ([[extractedBodyParts objectAtIndex:i] body]) {
|
||||
if (encoding && [encoding rangeOfString:@"base64"].location != NSNotFound)
|
||||
body = [[[extractedBodyParts objectAtIndex:i] body] dataByDecodingBase64];
|
||||
else
|
||||
body = [[extractedBodyParts objectAtIndex:i] body];
|
||||
|
||||
[self saveAttachment: body
|
||||
withMetadata: currentInfo];
|
||||
}
|
||||
}
|
||||
[contentDisposition release];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return a NGMimeMessage object with inline HTML images (<img src=data>) extracted as attachments (<img src=cid>).
|
||||
@@ -2271,6 +2233,41 @@ static NSString *userAgent = nil;
|
||||
return [self sendMailAndCopyToSent: YES];
|
||||
}
|
||||
|
||||
// Extract tmp files in NGMimeBuildMimeTempDirectory from NSArray and store locally
|
||||
// The tmp files will be deleted once the message sent
|
||||
- (void) addTmpFiles:(NSArray *) parts {
|
||||
NGMimeBodyPart *part;
|
||||
|
||||
for (part in parts) {
|
||||
NGMimeFileData *body;
|
||||
NSString *path;
|
||||
|
||||
body = [part body];
|
||||
if (body && [body isKindOfClass: [NGMimeFileData class]]) {
|
||||
path = [body path];
|
||||
if (path) {
|
||||
[tmpFiles addObject: path];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean temporary files
|
||||
- (void) cleanTmpFiles {
|
||||
NSString *path;
|
||||
NSFileManager *fm;
|
||||
|
||||
fm = [NSFileManager defaultManager];
|
||||
|
||||
for (path in tmpFiles) {
|
||||
if ([fm fileExistsAtPath: path])
|
||||
[fm removeFileAtPath: path handler: nil];
|
||||
}
|
||||
|
||||
// Clean tmp files
|
||||
[tmpFiles removeAllObjects];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -2316,8 +2313,10 @@ static NSString *userAgent = nil;
|
||||
inContext: context
|
||||
systemMessage: NO];
|
||||
|
||||
if (error)
|
||||
if (error) {
|
||||
[self cleanTmpFiles];
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// If the current user isn't part of the recipient list for encrypted emails
|
||||
@@ -2376,6 +2375,8 @@ static NSString *userAgent = nil;
|
||||
[imap4 doesMailboxExistAtURL: [container imap4URL]])
|
||||
[(SOGoDraftsFolder *) container expunge];
|
||||
|
||||
[self cleanTmpFiles];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ SOGo_HEADER_FILES = \
|
||||
JWT.h \
|
||||
\
|
||||
NGMimeBodyPart+SOGo.h \
|
||||
NGMimeFileData+SOGo.h \
|
||||
\
|
||||
SOGoMobileProvision.h
|
||||
|
||||
@@ -183,6 +184,7 @@ SOGo_OBJC_FILES = \
|
||||
JWT.m \
|
||||
\
|
||||
NGMimeBodyPart+SOGo.m \
|
||||
NGMimeFileData+SOGo.m \
|
||||
\
|
||||
SOGoMobileProvision.m
|
||||
|
||||
|
||||
+59
-12
@@ -1384,6 +1384,21 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
{
|
||||
if ([match length] > 0) {
|
||||
return [self fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
limit: -1];
|
||||
} else {
|
||||
return [NSMutableArray array];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) match
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) theDomain
|
||||
limit: (int) limit
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NGLdapConnection *ldapConnection;
|
||||
@@ -1392,6 +1407,8 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
NSMutableArray *contacts;
|
||||
EOQualifier *qualifier;
|
||||
unsigned int i;
|
||||
NSString *sortAttribute;
|
||||
BOOL sortReverse;
|
||||
|
||||
contacts = [NSMutableArray array];
|
||||
|
||||
@@ -1400,18 +1417,48 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
ldapConnection = [self _ldapConnection];
|
||||
qualifier = [self _qualifierForFilter: match onCriteria: criteria];
|
||||
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
if (limit > 0) {
|
||||
[ldapConnection setQuerySizeLimit: limit];
|
||||
}
|
||||
|
||||
if (limit > 0) {
|
||||
// Sort results
|
||||
sortAttribute = @"cn";
|
||||
sortReverse = NO;
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields
|
||||
sortAttribute: sortAttribute
|
||||
sortReverse: sortReverse];
|
||||
} else {
|
||||
// No sort results
|
||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
else /* we do it like before */
|
||||
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
|
||||
qualifier: qualifier
|
||||
attributes: _lookupFields];
|
||||
}
|
||||
|
||||
|
||||
i = 0;
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* NGMimeFileData+SOGo.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2023 Alinto
|
||||
*
|
||||
* Author: Sébastien Mizrahi <smizrahi@alinto.eu>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef NGMIMEFILEDATA_SOGO_H
|
||||
#define NGMIMEFILEDATA_SOGO_H
|
||||
|
||||
#import <NGMime/NGMimeFileData.h>
|
||||
|
||||
@interface NGMimeFileData (SOGoExtensions)
|
||||
|
||||
- (NSString *) path;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* NGMIMEFILEDATA_SOGO_H */
|
||||
@@ -0,0 +1,32 @@
|
||||
/* NGMimeFileData+SOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2023 Alinto
|
||||
*
|
||||
* Author: Sébastien Mizrahi <smizrahi@alinto.eu>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "NGMimeFileData+SOGo.h"
|
||||
|
||||
|
||||
@implementation NGMimeFileData (SOGoExtensions)
|
||||
|
||||
- (NSString *) path {
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -65,6 +65,7 @@
|
||||
- (id) objectFromJSONString;
|
||||
|
||||
/* bare email addresses */
|
||||
- (NSString *) mailDomain;
|
||||
- (NSString *) pureEMailAddress;
|
||||
|
||||
- (NSString *) asQPSubjectString: (NSString *) encoding;
|
||||
|
||||
@@ -609,6 +609,18 @@ static int cssEscapingCount;
|
||||
return newString;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) mailDomain
|
||||
{
|
||||
NSArray *mailSeparated;
|
||||
|
||||
mailSeparated = [self componentsSeparatedByString: @"@"];
|
||||
if([mailSeparated count] == 2)
|
||||
return [mailSeparated objectAtIndex: 1];
|
||||
[self logWithFormat: @"Error while extracting domain from : %@", self];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) pureEMailAddress
|
||||
{
|
||||
NSString *pureAddress;
|
||||
@@ -979,6 +991,18 @@ static int cssEscapingCount;
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<ifr***"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove <form
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B	

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

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

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

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

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

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

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

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

\\\\0]*m"
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"</for*"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove onload
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"onload="
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
|
||||
@@ -100,8 +100,19 @@
|
||||
if (data) {
|
||||
if ([data isKindOfClass: [NSString class]])
|
||||
ASSIGN (content, data);
|
||||
else
|
||||
ASSIGN (content, [NSString stringWithUTF8String:[data bytes]]);
|
||||
else {
|
||||
char lastByte;
|
||||
[data getBytes:&lastByte range:NSMakeRange([data length]-1, 1)];
|
||||
if (lastByte == 0x0) {
|
||||
// string is null terminated
|
||||
ASSIGN (content, [NSString stringWithUTF8String: [data bytes]]);
|
||||
} else {
|
||||
// string is not null terminated
|
||||
NSString* myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
ASSIGN (content, myString);
|
||||
[myString release];
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [objectRecord objectForKey: @"c_version"];
|
||||
if (data)
|
||||
|
||||
@@ -123,6 +123,8 @@
|
||||
SOGoTemplatesFolderName = "Templates";
|
||||
SOGoMailComposeMessageType = "html";
|
||||
SOGoMailComposeFontSize = "0";
|
||||
SOGoMailHideInlineAttachments = NO;
|
||||
SOGoMailDisplayFullEmail = NO;
|
||||
SOGoMailDisplayRemoteInlineImages = "never";
|
||||
SOGoMailCertificateEnabled = YES;
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
v = [self integerForKey: @"SOGoForwardConstraints"];
|
||||
|
||||
return (v > 2 ? 0 : v);
|
||||
return (v > 3 ? 0 : v);
|
||||
}
|
||||
|
||||
- (NSArray *) forwardConstraintsDomains
|
||||
|
||||
@@ -739,7 +739,8 @@ static NSArray *childRecordFields = nil;
|
||||
qualifier = aclQualifier;
|
||||
|
||||
// For Thunderbird, disable contact list
|
||||
if ([[context request] isThunderbird]) {
|
||||
// This will be removed when VCARD will be implemented
|
||||
if ([[context request] isThunderbird] && [self isKindOfClass: NSClassFromString(@"SOGoContactGCSFolder")]) {
|
||||
vlistExclusionQualifier = [EOQualifier qualifierWithQualifierFormat: @"c_component != 'vlist'"];
|
||||
qualifier = [[[EOAndQualifier alloc] initWithQualifiers:
|
||||
vlistExclusionQualifier,
|
||||
@@ -1191,7 +1192,8 @@ static NSArray *childRecordFields = nil;
|
||||
folder = [self ocsFolder];
|
||||
|
||||
// For Thunderbird, disable contact list
|
||||
if ([[context request] isThunderbird]) {
|
||||
// This will be removed when VCARD will be implemented
|
||||
if ([[context request] isThunderbird] && [self isKindOfClass: NSClassFromString(@"SOGoContactGCSFolder")]) {
|
||||
vlistExclusionQualifier = [EOQualifier qualifierWithQualifierFormat: @"c_component != 'vlist'"];
|
||||
qualifier = [[[EOAndQualifier alloc] initWithQualifiers:
|
||||
vlistExclusionQualifier,
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
NSDictionary *provisioning;
|
||||
NSError *error;
|
||||
NSString *payloadType, *prefix, *type;
|
||||
NSNumber *port;
|
||||
|
||||
activeUser = [context activeUser];
|
||||
serverURL = [context serverURL];
|
||||
@@ -57,11 +58,20 @@
|
||||
break;
|
||||
}
|
||||
|
||||
port = [serverURL port];
|
||||
if (!port) {
|
||||
if ([[serverURL scheme] isEqualToString:@"https"]) {
|
||||
port = [NSNumber numberWithInt: 443];
|
||||
} else {
|
||||
port = [NSNumber numberWithInt: 80];
|
||||
}
|
||||
}
|
||||
|
||||
provisioning = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSArray arrayWithObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithFormat:@"%@ %@", type, name], [NSString stringWithFormat:@"%@%@", prefix, @"AccountDescription"],
|
||||
[serverURL host], [NSString stringWithFormat:@"%@%@", prefix, @"HostName"],
|
||||
[serverURL port], [NSString stringWithFormat:@"%@%@", prefix, @"Port"],
|
||||
port, [NSString stringWithFormat:@"%@%@", prefix, @"Port"],
|
||||
path, [NSString stringWithFormat:@"%@%@", prefix, @"PrincipalURL"],
|
||||
[NSNumber numberWithBool:[[serverURL scheme] isEqualToString:@"https"]], [NSString stringWithFormat:@"%@%@", prefix, @"UseSSL"],
|
||||
[activeUser login], [NSString stringWithFormat:@"%@%@", prefix, @"Username"],
|
||||
|
||||
@@ -33,7 +33,7 @@ static const NSString *POLICY_MIN_DIGIT = @"POLICY_MIN_DIGIT";
|
||||
static const NSString *POLICY_MIN_SPECIAL_SYMBOLS = @"POLICY_MIN_SPECIAL_SYMBOLS";
|
||||
static const NSString *POLICY_MIN_LENGTH = @"POLICY_MIN_LENGTH";
|
||||
|
||||
static const NSString *SPECIAL_SYMBOL_ALLOWED = @"%$&*(){}!?\\@#.,:;+=";
|
||||
static const NSString *SPECIAL_SYMBOL_ALLOWED = @"%$&*(){}!?\\@#.,:;+=\\[\\]\\|<>\\/-_";
|
||||
|
||||
@implementation SOGoPasswordPolicy
|
||||
|
||||
|
||||
@@ -102,10 +102,12 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
EOAdaptorChannel *channel;
|
||||
NSDictionary *row;
|
||||
NSException *ex;
|
||||
NSString *sql, *value;
|
||||
NSString *sql, *result;
|
||||
id value;
|
||||
NSArray *attrs;
|
||||
|
||||
value = nil;
|
||||
result = nil;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
channel = [cm acquireOpenChannelForURL: tableURL];
|
||||
@@ -136,6 +138,12 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
value = [row objectForKey: fieldName];
|
||||
if (![value isNotNull])
|
||||
value = nil; /* we discard any NSNull instance */
|
||||
|
||||
if (value && [value isKindOfClass: [NSData class]]) {
|
||||
result = [NSString stringWithUTF8String: [value bytes]];
|
||||
} else if (value && [value isKindOfClass: [NSString class]]) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
[cm releaseChannel: channel];
|
||||
@@ -147,7 +155,7 @@ static const NSString *kCDefaultsLenKey = @"kCDefaultsLenKey";
|
||||
tableURL];
|
||||
}
|
||||
|
||||
return value;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *) generateSQLForInsert: (NSString *) jsonRepresentation
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain;
|
||||
- (NSArray *)fetchContactsMatching:(NSString *)filter
|
||||
withCriteria:(NSArray *)criteria
|
||||
inDomain:(NSString *)domain
|
||||
limit:(int)limit;
|
||||
|
||||
- (NSArray *) lookupContactsWithQualifier: (EOQualifier *) qualifier
|
||||
andSortOrdering: (EOSortOrdering *) ordering
|
||||
inDomain: (NSString *) domain;
|
||||
|
||||
@@ -130,6 +130,11 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
|
||||
- (NSString *) JWTSecret;
|
||||
|
||||
- (NSArray *) disableSharing;
|
||||
- (NSArray *) disableSharingAnyAuthUser;
|
||||
- (NSArray *) disableExport;
|
||||
|
||||
- (BOOL) enableGlobalAddressBookFirstEntries;
|
||||
- (int) globalAddressBookFirstEntriesCount;
|
||||
|
||||
- (BOOL)isURLEncryptionEnabled;
|
||||
- (NSString *)urlEncryptionPassphrase;
|
||||
|
||||
@@ -835,4 +835,47 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
|
||||
return passphrase;
|
||||
}
|
||||
|
||||
- (NSArray *) disableSharingAnyAuthUser
|
||||
{
|
||||
static NSArray *disableSharingAnyAuthUser = nil;
|
||||
|
||||
if (!disableSharingAnyAuthUser)
|
||||
{
|
||||
disableSharingAnyAuthUser = [self stringArrayForKey: @"SOGoDisableSharingAnyAuthUser"];
|
||||
[disableSharingAnyAuthUser retain];
|
||||
}
|
||||
|
||||
return disableSharingAnyAuthUser;
|
||||
}
|
||||
|
||||
- (NSArray *) disableExport
|
||||
{
|
||||
static NSArray *disableExport = nil;
|
||||
|
||||
if (!disableExport)
|
||||
{
|
||||
disableExport = [self stringArrayForKey: @"SOGoDisableExport"];
|
||||
[disableExport retain];
|
||||
}
|
||||
|
||||
return disableExport;
|
||||
}
|
||||
|
||||
- (BOOL) globalAddressBookFirstEntriesEnabled
|
||||
{
|
||||
return [self boolForKey: @"SOGoGlobalAddressBookFirstEntries"];
|
||||
}
|
||||
|
||||
- (int) globalAddressBookFirstEntriesCount
|
||||
{
|
||||
int v;
|
||||
|
||||
v = [self integerForKey: @"SOGoGlobalAddressBookFirstEntriesCount"];
|
||||
|
||||
if (!v)
|
||||
v = 100;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -156,6 +156,9 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
|
||||
- (void) setMailComposeFontSize: (int) newValue;
|
||||
- (int) mailComposeFontSize;
|
||||
|
||||
- (void) setMailDisplayFullEmail: (BOOL *) newValue;
|
||||
- (BOOL *) mailDisplayFullEmail;
|
||||
|
||||
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue;
|
||||
- (NSString *) mailDisplayRemoteInlineImages;
|
||||
|
||||
@@ -228,8 +231,11 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
|
||||
- (void) setMailLabelsColors: (NSDictionary *) newValues;
|
||||
- (NSDictionary *) mailLabelsColors;
|
||||
|
||||
- (void)setHideInlineAttachments:(BOOL)newValue;
|
||||
- (BOOL)hideInlineAttachments;
|
||||
|
||||
/* calendar */
|
||||
- (void) setCalendarCategories: (NSArray *) newValues;
|
||||
- (void)setCalendarCategories : (NSArray *)newValues;
|
||||
- (NSArray *) calendarCategories;
|
||||
|
||||
- (void) setCalendarCategoriesColors: (NSDictionary *) newValues;
|
||||
|
||||
@@ -631,6 +631,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
|
||||
return [self integerForKey: @"SOGoMailComposeFontSize"];
|
||||
}
|
||||
|
||||
- (void) setMailDisplayFullEmail: (BOOL *) newValue
|
||||
{
|
||||
[self setBool: newValue forKey: @"SOGoMailDisplayFullEmail"];
|
||||
}
|
||||
|
||||
- (BOOL *) mailDisplayFullEmail;
|
||||
{
|
||||
return [self boolForKey: @"SOGoMailDisplayFullEmail"];
|
||||
}
|
||||
|
||||
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue
|
||||
{
|
||||
[self setObject: newValue forKey: @"SOGoMailDisplayRemoteInlineImages"];
|
||||
@@ -959,6 +969,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
|
||||
return [self objectForKey: @"SOGoMailLabelsColors"];
|
||||
}
|
||||
|
||||
- (void) setHideInlineAttachments: (BOOL) newValue
|
||||
{
|
||||
[self setBool: newValue forKey: @"SOGoMailHideInlineAttachments"];
|
||||
}
|
||||
|
||||
- (BOOL) hideInlineAttachments
|
||||
{
|
||||
return [self boolForKey: @"SOGoMailHideInlineAttachments"];
|
||||
}
|
||||
|
||||
- (void) setSieveFilters: (NSArray *) newValue
|
||||
{
|
||||
[self setObject: newValue forKey: @"SOGoSieveFilters"];
|
||||
|
||||
@@ -924,6 +924,22 @@
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain
|
||||
|
||||
{
|
||||
if ([filter length] > 0) {
|
||||
return [self fetchContactsMatching: (NSString *) filter
|
||||
withCriteria: (NSArray *) criteria
|
||||
inDomain: (NSString *) domain
|
||||
limit: -1];
|
||||
} else {
|
||||
return [NSMutableArray array];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)fetchContactsMatching: (NSString *)filter
|
||||
withCriteria: (NSArray *)criteria
|
||||
inDomain: (NSString *)domain
|
||||
limit: (int)limit
|
||||
{
|
||||
EOAdaptorChannel *channel;
|
||||
NSEnumerator *criteriaList;
|
||||
@@ -994,6 +1010,8 @@
|
||||
[sql appendFormat: @" AND %@ IS NULL", _domainField];
|
||||
}
|
||||
|
||||
if (limit > 0)
|
||||
[sql appendFormat: @" ORDER BY c_cn ASC LIMIT %i", limit];
|
||||
ex = [channel evaluateExpressionX: sql];
|
||||
if (!ex)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user