(fix) remaining S/MIME fixes to handle image/CIDs in HTML mails
parent
341e5cbab0
commit
511aa63a34
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2007-2016 Inverse inc.
|
Copyright (C) 2007-2018 Inverse inc.
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
|
|
||||||
This file is part of SOGo.
|
This file is part of SOGo.
|
||||||
|
@ -799,6 +799,12 @@ static NSString *userAgent = nil;
|
||||||
//
|
//
|
||||||
- (void) _fileAttachmentsFromPart: (id) thePart
|
- (void) _fileAttachmentsFromPart: (id) thePart
|
||||||
{
|
{
|
||||||
|
// Small hack to avoid SOPE's stupid behavior to wrap a multipart
|
||||||
|
// object in a NGMimeBodyPart.
|
||||||
|
if ([thePart isKindOfClass: [NGMimeBodyPart class]] &&
|
||||||
|
[[[thePart contentType] type] isEqualToString: @"multipart"])
|
||||||
|
thePart = [thePart body];
|
||||||
|
|
||||||
if ([thePart isKindOfClass: [NGMimeBodyPart class]])
|
if ([thePart isKindOfClass: [NGMimeBodyPart class]])
|
||||||
{
|
{
|
||||||
NSString *filename, *mimeType;
|
NSString *filename, *mimeType;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#import <NGMime/NGMimeMultipartBody.h>
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
|
|
||||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||||
|
#import <SoObjects/SOGo/NSObject+Utilities.h>
|
||||||
|
|
||||||
#import "NSData+SMIME.h"
|
#import "NSData+SMIME.h"
|
||||||
#import "NSDictionary+Mail.h"
|
#import "NSDictionary+Mail.h"
|
||||||
|
@ -169,13 +170,47 @@ static BOOL debugOn = NO;
|
||||||
inContext: (WOContext *) localContext
|
inContext: (WOContext *) localContext
|
||||||
{
|
{
|
||||||
// TODO: we might want to check for existence prior controller creation
|
// TODO: we might want to check for existence prior controller creation
|
||||||
Class clazz;
|
|
||||||
NSArray *subParts;
|
|
||||||
unsigned int nbr;
|
|
||||||
id obj;
|
|
||||||
NSDictionary *subPart, *infos;
|
NSDictionary *subPart, *infos;
|
||||||
|
NSString *mimeType;
|
||||||
|
NSArray *subParts;
|
||||||
|
Class clazz;
|
||||||
|
id o, obj;
|
||||||
|
|
||||||
|
unsigned int nbr;
|
||||||
|
|
||||||
nbr = [key intValue];
|
nbr = [key intValue];
|
||||||
|
o = [self container];
|
||||||
|
|
||||||
|
while (![o isKindOfClass: [SOGoMailObject class]])
|
||||||
|
o = [o container];
|
||||||
|
|
||||||
|
if ([o isEncrypted])
|
||||||
|
{
|
||||||
|
NSData *certificate;
|
||||||
|
NGMimeMessage *m;
|
||||||
|
id part;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
certificate = [[self mailAccountFolder] certificate];
|
||||||
|
m = [[o content] messageFromEncryptedDataAndCertificate: certificate];
|
||||||
|
part = [m body];
|
||||||
|
|
||||||
|
for (i = 0; i < [[self bodyPartPath] count]; i++)
|
||||||
|
{
|
||||||
|
nbr = [[[self bodyPartPath] objectAtIndex: i] intValue]-1;
|
||||||
|
part = [[part parts] objectAtIndex: nbr];;
|
||||||
|
}
|
||||||
|
|
||||||
|
//part = [[[m body] parts] objectAtIndex: ([key intValue]-1)];
|
||||||
|
part = [[part parts] objectAtIndex: ([key intValue]-1)];
|
||||||
|
mimeType = [[part contentType] stringValue];
|
||||||
|
clazz = [SOGoMailBodyPart bodyPartClassForMimeType: mimeType
|
||||||
|
inContext: localContext];
|
||||||
|
obj = [clazz objectWithName:key inContainer: self];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
infos = [self partInfo];
|
infos = [self partInfo];
|
||||||
subParts = [infos objectForKey: @"parts"];
|
subParts = [infos objectForKey: @"parts"];
|
||||||
if (!subParts)
|
if (!subParts)
|
||||||
|
@ -184,20 +219,16 @@ static BOOL debugOn = NO;
|
||||||
if (nbr > 0 && nbr < ([subParts count] + 1))
|
if (nbr > 0 && nbr < ([subParts count] + 1))
|
||||||
{
|
{
|
||||||
subPart = [subParts objectAtIndex: nbr - 1];
|
subPart = [subParts objectAtIndex: nbr - 1];
|
||||||
clazz
|
mimeType = [subPart keysWithFormat: @"%{type}/%{subtype}"];
|
||||||
= [[self class] bodyPartClassForMimeType:
|
clazz = [[self class] bodyPartClassForMimeType: mimeType
|
||||||
[subPart keysWithFormat: @"%{type}/%{subtype}"]
|
|
||||||
inContext: localContext];
|
inContext: localContext];
|
||||||
obj = [clazz objectWithName: key inContainer: self];
|
obj = [clazz objectWithName: key inContainer: self];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
obj = self;
|
obj = self;
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
// clazz = [SOGoMailBodyPart bodyPartClassForKey: _key
|
|
||||||
// inContext: _ctx];
|
|
||||||
|
|
||||||
// return [clazz objectWithName: _key inContainer: self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) filename
|
- (NSString *) filename
|
||||||
|
@ -304,23 +335,29 @@ static BOOL debugOn = NO;
|
||||||
if ([o isEncrypted])
|
if ([o isEncrypted])
|
||||||
{
|
{
|
||||||
NSData *certificate;
|
NSData *certificate;
|
||||||
|
|
||||||
certificate = [[self mailAccountFolder] certificate];
|
|
||||||
|
|
||||||
// If we got a user certificate, let's use it. Otherwise we fallback
|
|
||||||
// to the current BLOB fetching code.
|
|
||||||
if (certificate)
|
|
||||||
{
|
|
||||||
NGMimeMessage *m;
|
NGMimeMessage *m;
|
||||||
id part;
|
id part;
|
||||||
|
|
||||||
m = [[container content] messageFromEncryptedDataAndCertificate: certificate];
|
unsigned int i, nbr;
|
||||||
part = [[[m body] parts] objectAtIndex: ([[self nameInContainer] intValue]-1)];
|
|
||||||
|
// No need to check if the cert is valid as we already do so
|
||||||
|
// in SOGoMailObject.
|
||||||
|
certificate = [[self mailAccountFolder] certificate];
|
||||||
|
|
||||||
|
m = [[o content] messageFromEncryptedDataAndCertificate: certificate];
|
||||||
|
part = [m body];
|
||||||
|
|
||||||
|
for (i = 0; i < [[self bodyPartPath] count]; i++)
|
||||||
|
{
|
||||||
|
nbr = [[[self bodyPartPath] objectAtIndex: i] intValue]-1;
|
||||||
|
part = [[part parts] objectAtIndex: nbr];;
|
||||||
|
}
|
||||||
|
|
||||||
return [part body];
|
return [part body];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// The mail is not encrypted, lets fetch the body party normally
|
||||||
|
// straight from the IMAP server
|
||||||
return [self fetchBLOBWithPeek: NO];
|
return [self fetchBLOBWithPeek: NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* NSObject+Utilities.h - this file is part of SOGo
|
/* NSObject+Utilities.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2015 Inverse inc.
|
* Copyright (C) 2007-2017 Inverse inc.
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#import <DOM/DOMProtocols.h>
|
#import <DOM/DOMProtocols.h>
|
||||||
|
|
||||||
|
@class NSArray;
|
||||||
@class NSString;
|
@class NSString;
|
||||||
@class WOContext;
|
@class WOContext;
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@
|
||||||
|
|
||||||
+ (void) memoryStatistics;
|
+ (void) memoryStatistics;
|
||||||
|
|
||||||
|
- (NSArray *) parts;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* NSOBJECT+UTILITIES_H */
|
#endif /* NSOBJECT+UTILITIES_H */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* NSObject+Utilities.m - this file is part of SOGo
|
/* NSObject+Utilities.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2015 Inverse inc.
|
* Copyright (C) 2007-2018 Inverse inc.
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,6 +24,9 @@
|
||||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||||
#import <NGObjWeb/WORequest.h>
|
#import <NGObjWeb/WORequest.h>
|
||||||
|
|
||||||
|
#import <NGMime/NGMimeBodyPart.h>
|
||||||
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
|
|
||||||
#import "NSDictionary+Utilities.h"
|
#import "NSDictionary+Utilities.h"
|
||||||
#import "SOGoUser.h"
|
#import "SOGoUser.h"
|
||||||
#import "SOGoUserDefaults.h"
|
#import "SOGoUserDefaults.h"
|
||||||
|
@ -147,4 +150,20 @@
|
||||||
printf("Done!\n");
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Small hack to avoid SOPE's stupid behavior to wrap a multipart
|
||||||
|
// object in a NGMimeBodyPart.
|
||||||
|
//
|
||||||
|
- (NSArray *) parts
|
||||||
|
{
|
||||||
|
if ([self isKindOfClass: [NGMimeMultipartBody class]])
|
||||||
|
return [self parts];
|
||||||
|
|
||||||
|
if ([self isKindOfClass: [NGMimeBodyPart class]] &&
|
||||||
|
[[(id)self body] isKindOfClass: [NGMimeMultipartBody class]])
|
||||||
|
return [[(id)self body] parts];
|
||||||
|
|
||||||
|
return [NSArray array];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2007-2017 Inverse inc.
|
Copyright (C) 2007-2018 Inverse inc.
|
||||||
Copyright (C) 2004 SKYRIX Software AG
|
Copyright (C) 2004 SKYRIX Software AG
|
||||||
|
|
||||||
This file is part of SOGo.
|
This file is part of SOGo.
|
||||||
|
@ -23,8 +23,11 @@
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSNull.h>
|
#import <Foundation/NSNull.h>
|
||||||
|
|
||||||
|
#import <SOGo/NSObject+Utilities.h>
|
||||||
|
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
#import <NGMail/NGMimeMessageParser.h>
|
#import <NGMail/NGMimeMessageParser.h>
|
||||||
|
#import <NGMime/NGMimeBodyPart.h>
|
||||||
#import <NGMime/NGMimeMultipartBody.h>
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
#import <NGMime/NGMimeType.h>
|
#import <NGMime/NGMimeType.h>
|
||||||
|
|
||||||
|
@ -65,20 +68,20 @@
|
||||||
|
|
||||||
NSUInteger i, count;
|
NSUInteger i, count;
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
childParts = [[self decodedFlatContent] parts];
|
childParts = [[self decodedFlatContent] parts];
|
||||||
else
|
else
|
||||||
childParts = [[self bodyInfo] valueForKey:@"parts"];
|
childParts = [[self bodyInfo] valueForKey: @"parts"];
|
||||||
|
|
||||||
count = [childParts count];
|
count = [childParts count];
|
||||||
types = [NSMutableArray arrayWithCapacity: count];
|
types = [NSMutableArray arrayWithCapacity: count];
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
{
|
{
|
||||||
mt = [[[[[self decodedFlatContent] parts] objectAtIndex: i] contentType] type];
|
mt = [[[childParts objectAtIndex: i] contentType] type];
|
||||||
st = [[[[[self decodedFlatContent] parts] objectAtIndex: i] contentType] subType];
|
st = [[[childParts objectAtIndex: i] contentType] subType];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -141,20 +144,19 @@
|
||||||
{
|
{
|
||||||
NSUInteger idx;
|
NSUInteger idx;
|
||||||
|
|
||||||
[childInfo release]; childInfo = nil;
|
DESTROY(childInfo);
|
||||||
childIndex = 0;
|
childIndex = 0;
|
||||||
|
|
||||||
idx = [self _selectPartIndexFromTypes: [self childPartTypes]];
|
idx = [self _selectPartIndexFromTypes: [self childPartTypes]];
|
||||||
if (idx == NSNotFound)
|
if (idx == NSNotFound)
|
||||||
{
|
{
|
||||||
[self errorWithFormat:@"could not select a part of types: %@",
|
[self errorWithFormat:@"could not select a part of types: %@", [self childPartTypes]];
|
||||||
[self childPartTypes]];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
childIndex = idx + 1;
|
childIndex = idx + 1;
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
childInfo = [[[[self decodedFlatContent] parts] objectAtIndex: idx] bodyInfo];
|
childInfo = [[[[self decodedFlatContent] parts] objectAtIndex: idx] bodyInfo];
|
||||||
else
|
else
|
||||||
childInfo = [[[self bodyInfo] valueForKey:@"parts"] objectAtIndex: idx];
|
childInfo = [[[self bodyInfo] valueForKey:@"parts"] objectAtIndex: idx];
|
||||||
|
@ -172,17 +174,18 @@
|
||||||
return [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
return [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) renderedPart {
|
- (id) renderedPart
|
||||||
|
{
|
||||||
id info, viewer;
|
id info, viewer;
|
||||||
NSArray *parts;
|
NSArray *parts;
|
||||||
NSMutableArray *renderedParts;
|
NSMutableArray *renderedParts;
|
||||||
NSString *preferredType;
|
NSString *preferredType;
|
||||||
NSUInteger i, max;
|
NSUInteger i, max;
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
parts = [[self decodedFlatContent] parts];
|
parts = [[self decodedFlatContent] parts];
|
||||||
else
|
else
|
||||||
parts = [[self bodyInfo] valueForKey:@"parts"];
|
parts = [[self bodyInfo] valueForKey: @"parts"];
|
||||||
|
|
||||||
max = [parts count];
|
max = [parts count];
|
||||||
renderedParts = [NSMutableArray arrayWithCapacity: max];
|
renderedParts = [NSMutableArray arrayWithCapacity: max];
|
||||||
|
@ -190,7 +193,7 @@
|
||||||
{
|
{
|
||||||
[self setChildIndex: i];
|
[self setChildIndex: i];
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
||||||
else
|
else
|
||||||
[self setChildInfo: [parts objectAtIndex: i]];
|
[self setChildInfo: [parts objectAtIndex: i]];
|
||||||
|
@ -200,7 +203,7 @@
|
||||||
[viewer setBodyInfo: info];
|
[viewer setBodyInfo: info];
|
||||||
[viewer setPartPath: [self childPartPath]];
|
[viewer setPartPath: [self childPartPath]];
|
||||||
[viewer setAttachmentIds: attachmentIds];
|
[viewer setAttachmentIds: attachmentIds];
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
||||||
[renderedParts addObject: [viewer renderedPart]];
|
[renderedParts addObject: [viewer renderedPart]];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2017 Inverse inc.
|
Copyright (C) 2017-2018 Inverse inc.
|
||||||
|
|
||||||
This file is part of SOGo.
|
This file is part of SOGo.
|
||||||
|
|
||||||
|
@ -21,12 +21,17 @@
|
||||||
|
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSNull.h>
|
#import <Foundation/NSNull.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
#import <NGMail/NGMimeMessageParser.h>
|
#import <NGMime/NGMimeBodyPart.h>
|
||||||
|
#import <NGMime/NGMimeHeaderFields.h>
|
||||||
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
#import <NGMime/NGMimeType.h>
|
#import <NGMime/NGMimeType.h>
|
||||||
|
#import <NGMail/NGMimeMessageParser.h>
|
||||||
|
|
||||||
#import <SoObjects/Mailer/NSData+SMIME.h>
|
#import <SoObjects/Mailer/NSData+SMIME.h>
|
||||||
|
#import <SoObjects/Mailer/NSString+Mail.h>
|
||||||
#import <SoObjects/Mailer/SOGoMailAccount.h>
|
#import <SoObjects/Mailer/SOGoMailAccount.h>
|
||||||
#import <SoObjects/Mailer/SOGoMailObject.h>
|
#import <SoObjects/Mailer/SOGoMailObject.h>
|
||||||
#import <UI/MailerUI/WOContext+UIxMailer.h>
|
#import <UI/MailerUI/WOContext+UIxMailer.h>
|
||||||
|
@ -36,7 +41,45 @@
|
||||||
|
|
||||||
@implementation UIxMailPartEncryptedViewer
|
@implementation UIxMailPartEncryptedViewer
|
||||||
|
|
||||||
/* nested viewers */
|
- (void) _attachmentIdsFromBodyPart: (id) thePart
|
||||||
|
partPath: (NSString *) thePartPath
|
||||||
|
{
|
||||||
|
// Small hack to avoid SOPE's stupid behavior to wrap a multipart
|
||||||
|
// object in a NGMimeBodyPart.
|
||||||
|
if ([thePart isKindOfClass: [NGMimeBodyPart class]] &&
|
||||||
|
[[[thePart contentType] type] isEqualToString: @"multipart"])
|
||||||
|
thePart = [thePart body];
|
||||||
|
|
||||||
|
if ([thePart isKindOfClass: [NGMimeBodyPart class]])
|
||||||
|
{
|
||||||
|
NSString *filename, *mimeType;
|
||||||
|
|
||||||
|
mimeType = [[thePart contentType] stringValue];
|
||||||
|
filename = [(NGMimeContentDispositionHeaderField *)[thePart headerForKey: @"content-disposition"] filename];
|
||||||
|
|
||||||
|
if (!filename)
|
||||||
|
filename = [mimeType asPreferredFilenameUsingPath: nil];
|
||||||
|
|
||||||
|
if (filename)
|
||||||
|
{
|
||||||
|
[(id)attachmentIds setObject: [NSString stringWithFormat: @"%@%@%@",
|
||||||
|
[[self clientObject] baseURLInContext: [self context]],
|
||||||
|
thePartPath,
|
||||||
|
filename]
|
||||||
|
forKey: [NSString stringWithFormat: @"<%@>", filename]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ([thePart isKindOfClass: [NGMimeMultipartBody class]])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < [[thePart parts] count]; i++)
|
||||||
|
{
|
||||||
|
[self _attachmentIdsFromBodyPart: [[thePart parts] objectAtIndex: i]
|
||||||
|
partPath: [NSString stringWithFormat: @"%@%d/", thePartPath, i+1]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id) contentViewerComponent
|
- (id) contentViewerComponent
|
||||||
{
|
{
|
||||||
|
@ -49,7 +92,6 @@
|
||||||
- (id) renderedPart
|
- (id) renderedPart
|
||||||
{
|
{
|
||||||
NSData *certificate, *decryptedData, *encryptedData;
|
NSData *certificate, *decryptedData, *encryptedData;
|
||||||
|
|
||||||
id info, viewer;
|
id info, viewer;
|
||||||
|
|
||||||
certificate = [[[self clientObject] mailAccountFolder] certificate];
|
certificate = [[[self clientObject] mailAccountFolder] certificate];
|
||||||
|
@ -71,16 +113,25 @@
|
||||||
[viewer setFlatContent: decryptedData];
|
[viewer setFlatContent: decryptedData];
|
||||||
[viewer setDecodedContent: [part body]];
|
[viewer setDecodedContent: [part body]];
|
||||||
|
|
||||||
|
// attachmentIds is empty in an ecrypted email as the IMAP body structure
|
||||||
|
// is of course not available for file attachments
|
||||||
|
[self _attachmentIdsFromBodyPart: [part body] partPath: @""];
|
||||||
|
[viewer setAttachmentIds: attachmentIds];
|
||||||
|
|
||||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[self className], @"type",
|
[self className], @"type",
|
||||||
|
[NSNumber numberWithBool: YES], @"valid",
|
||||||
[NSArray arrayWithObject: [viewer renderedPart]], @"content",
|
[NSArray arrayWithObject: [viewer renderedPart]], @"content",
|
||||||
nil];
|
nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Decryption failed, let's return something else...
|
// Decryption failed, let's return something else...
|
||||||
// FIXME - does not work for now.
|
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
return nil;
|
[self className], @"type",
|
||||||
|
[NSNumber numberWithBool: NO], @"valid",
|
||||||
|
[NSArray array], @"content",
|
||||||
|
nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end /* UIxMailPartAlternativeViewer */
|
@end /* UIxMailPartAlternativeViewer */
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2007-2017 Inverse inc.
|
Copyright (C) 2007-2018 Inverse inc.
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of SOGo
|
This file is part of SOGo
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
|
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
|
|
||||||
|
#import <SOGo/NSObject+Utilities.h>
|
||||||
|
|
||||||
|
#import <NGMime/NGMimeBodyPart.h>
|
||||||
#import <NGMime/NGMimeMultipartBody.h>
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
|
|
||||||
#import <UI/MailerUI/WOContext+UIxMailer.h>
|
#import <UI/MailerUI/WOContext+UIxMailer.h>
|
||||||
|
@ -31,24 +34,25 @@
|
||||||
|
|
||||||
@implementation UIxMailPartMixedViewer
|
@implementation UIxMailPartMixedViewer
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void) dealloc
|
||||||
|
{
|
||||||
[self->childInfo release];
|
[self->childInfo release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* caches */
|
- (void)resetBodyInfoCaches
|
||||||
|
{
|
||||||
- (void)resetBodyInfoCaches {
|
DESTROY(self->childInfo);
|
||||||
[self->childInfo release]; self->childInfo = nil;
|
|
||||||
[super resetBodyInfoCaches];
|
[super resetBodyInfoCaches];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* accessors */
|
- (void) setChildInfo:(id)_info
|
||||||
|
{
|
||||||
- (void)setChildInfo:(id)_info {
|
|
||||||
ASSIGN(self->childInfo, _info);
|
ASSIGN(self->childInfo, _info);
|
||||||
}
|
}
|
||||||
- (id)childInfo {
|
|
||||||
|
- (id) childInfo
|
||||||
|
{
|
||||||
return self->childInfo;
|
return self->childInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +60,7 @@
|
||||||
{
|
{
|
||||||
self->childIndex = _index;
|
self->childIndex = _index;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) childIndex
|
- (NSUInteger) childIndex
|
||||||
{
|
{
|
||||||
return self->childIndex;
|
return self->childIndex;
|
||||||
|
@ -67,7 +72,7 @@
|
||||||
(unsigned int) ([self childIndex] + 1)];
|
(unsigned int) ([self childIndex] + 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)childPartPath
|
- (id) childPartPath
|
||||||
{
|
{
|
||||||
NSArray *pp;
|
NSArray *pp;
|
||||||
|
|
||||||
|
@ -96,7 +101,7 @@
|
||||||
|
|
||||||
NSUInteger i, max;
|
NSUInteger i, max;
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
parts = [[self decodedFlatContent] parts];
|
parts = [[self decodedFlatContent] parts];
|
||||||
else
|
else
|
||||||
parts = [[self bodyInfo] valueForKey: @"parts"];
|
parts = [[self bodyInfo] valueForKey: @"parts"];
|
||||||
|
@ -108,7 +113,7 @@
|
||||||
{
|
{
|
||||||
[self setChildIndex: i];
|
[self setChildIndex: i];
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
||||||
else
|
else
|
||||||
[self setChildInfo: [parts objectAtIndex: i]];
|
[self setChildInfo: [parts objectAtIndex: i]];
|
||||||
|
@ -117,9 +122,10 @@
|
||||||
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||||
[viewer setBodyInfo: info];
|
[viewer setBodyInfo: info];
|
||||||
[viewer setPartPath: [self childPartPath]];
|
[viewer setPartPath: [self childPartPath]];
|
||||||
[viewer setAttachmentIds: attachmentIds];
|
if ([self decodedFlatContent])
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
|
||||||
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
[viewer setDecodedContent: [parts objectAtIndex: i]];
|
||||||
|
[viewer setAttachmentIds: attachmentIds];
|
||||||
|
|
||||||
[renderedParts addObject: [viewer renderedPart]];
|
[renderedParts addObject: [viewer renderedPart]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@
|
||||||
|
|
||||||
NSUInteger i, max;
|
NSUInteger i, max;
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
parts = [[self decodedFlatContent] parts];
|
parts = [[self decodedFlatContent] parts];
|
||||||
else
|
else
|
||||||
parts = [[self bodyInfo] objectForKey: @"parts"];
|
parts = [[self bodyInfo] objectForKey: @"parts"];
|
||||||
|
@ -259,7 +259,7 @@
|
||||||
{
|
{
|
||||||
[self setChildIndex: i];
|
[self setChildIndex: i];
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
[self setChildInfo: [[parts objectAtIndex: i] bodyInfo]];
|
||||||
else
|
else
|
||||||
[self setChildInfo: [parts objectAtIndex: i]];
|
[self setChildInfo: [parts objectAtIndex: i]];
|
||||||
|
@ -268,10 +268,11 @@
|
||||||
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||||
[viewer setBodyInfo: info];
|
[viewer setBodyInfo: info];
|
||||||
[viewer setPartPath: [self childPartPath]];
|
[viewer setPartPath: [self childPartPath]];
|
||||||
[viewer setAttachmentIds: attachmentIds];
|
|
||||||
|
|
||||||
if ([[self decodedFlatContent] isKindOfClass: [NGMimeMultipartBody class]])
|
if ([self decodedFlatContent])
|
||||||
[viewer setDecodedContent: [[parts objectAtIndex: i] body]];
|
[viewer setDecodedContent: [[parts objectAtIndex: i] body]];
|
||||||
|
|
||||||
|
[viewer setAttachmentIds: attachmentIds];
|
||||||
[renderedParts addObject: [viewer renderedPart]];
|
[renderedParts addObject: [viewer renderedPart]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -214,8 +214,7 @@
|
||||||
// but rather directly with NGMime objects.
|
// but rather directly with NGMime objects.
|
||||||
if ([content isKindOfClass: [NSData class]])
|
if ([content isKindOfClass: [NSData class]])
|
||||||
{
|
{
|
||||||
charset = [[bodyInfo objectForKey:@"parameterList"]
|
charset = [[bodyInfo objectForKey: @"parameterList"] objectForKey: @"charset"];
|
||||||
objectForKey: @"charset"];
|
|
||||||
s = [content bodyStringFromCharset: charset];
|
s = [content bodyStringFromCharset: charset];
|
||||||
}
|
}
|
||||||
else if ([content isKindOfClass: [NGMimeBodyPart class]] ||
|
else if ([content isKindOfClass: [NGMimeBodyPart class]] ||
|
||||||
|
|
|
@ -203,7 +203,7 @@ static BOOL showNamedTextAttachmentsInline = NO;
|
||||||
else if ([mt isEqualToString: @"text"])
|
else if ([mt isEqualToString: @"text"])
|
||||||
{
|
{
|
||||||
if ([st isEqualToString: @"plain"] || [st isEqualToString: @"html"]) {
|
if ([st isEqualToString: @"plain"] || [st isEqualToString: @"html"]) {
|
||||||
if (!showNamedTextAttachmentsInline && [self _shouldDisplayAsAttachment: _info textPart:YES])
|
if (!showNamedTextAttachmentsInline && [self _shouldDisplayAsAttachment: _info textPart: YES])
|
||||||
return [self linkViewer];
|
return [self linkViewer];
|
||||||
|
|
||||||
return [st isEqualToString: @"html"]
|
return [st isEqualToString: @"html"]
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse inc.
|
* Copyright (C) 2006 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2, or (at your option)
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
|
|
@ -226,6 +226,8 @@ static NSString *mailETag = nil;
|
||||||
viewer = [[context mailRenderingContext] viewerForBodyInfo: info];
|
viewer = [[context mailRenderingContext] viewerForBodyInfo: info];
|
||||||
[viewer setBodyInfo: info];
|
[viewer setBodyInfo: info];
|
||||||
|
|
||||||
|
if (![[self clientObject] isEncrypted])
|
||||||
|
{
|
||||||
max = [[self attachmentAttrs] count];
|
max = [[self attachmentAttrs] count];
|
||||||
attachmentIds = [NSMutableDictionary dictionaryWithCapacity: max];
|
attachmentIds = [NSMutableDictionary dictionaryWithCapacity: max];
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
|
@ -238,7 +240,12 @@ static NSString *mailETag = nil;
|
||||||
[attachmentIds setObject: [attributes objectForKey: @"url"]
|
[attachmentIds setObject: [attributes objectForKey: @"url"]
|
||||||
forKey: [attributes objectForKey: @"bodyId"]];
|
forKey: [attributes objectForKey: @"bodyId"]];
|
||||||
}
|
}
|
||||||
|
// Attachment IDs will be decoded in UIxMailPartEncryptedViewer for
|
||||||
|
// S/MIME encrypted emails with file attachments.
|
||||||
[viewer setAttachmentIds: attachmentIds];
|
[viewer setAttachmentIds: attachmentIds];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[viewer setAttachmentIds: [NSMutableDictionary dictionary]];
|
||||||
|
|
||||||
// If we are looking at a S/MIME signed mail which wasn't sent
|
// If we are looking at a S/MIME signed mail which wasn't sent
|
||||||
// by our actual active user, we update the certificate of that
|
// by our actual active user, we update the certificate of that
|
||||||
|
|
Loading…
Reference in New Issue