Compare commits

...
Author SHA1 Message Date
smizrahi 34e396ddee feat(mail): Deletion of mail older than x. Closes #6023. 2024-11-20 16:43:24 +01:00
smizrahi d5e86f7387 feat(mail): Deletion of mail older than x. Closes #6023. 2024-11-20 16:34:30 +01:00
smizrahi bce575a53d feat(mail): Deletion of mail older than x 2024-11-16 09:49:55 +01:00
smizrahi cd0324dd49 Add log for _fixDates 2024-11-12 16:21:12 +01:00
smizrahi 581b2c1912 Revert "Revert "fix(calendar): Fix issue where EXDATE removes modified occurence. The behavior is now identical to G Agenda. This fix may reduce the 'missing exception error'.""
This reverts commit ec20ea1b45d35f9d63066baf324fa6726b4e910e.
2024-11-12 16:21:12 +01:00
smizrahi 9a9d968756 Revert "fix(calendar): Fix issue where EXDATE removes modified occurence. The behavior is now identical to G Agenda. This fix may reduce the 'missing exception error'."
This reverts commit 5bab72726a.
2024-11-12 16:21:12 +01:00
Hivert Quentin fe003eeef5 chore(js/css): update generated files 2024-11-07 01:00:36 -05:00
smizrahi a09f4d8f49 fix(mail): Fix ckeditor margin for to make difference between line breaks and paragraph. Fixes #6056. 2024-11-06 17:56:02 +01:00
smizrahi 617c1bbc64 fix(mail): Correct attachment handling when creating emails from templates 2024-11-06 16:48:39 +01:00
smizrahi 5bab72726a fix(calendar): Fix issue where EXDATE removes modified occurence. The behavior is now identical to G Agenda. This fix may reduce the 'missing exception error'. 2024-11-06 09:15:12 +01:00
Hivert Quentin 01863987dd fix(calendar): fix commit f1257088 2024-11-04 10:22:08 +01:00
Hivert Quentin f1257088f2 fix(calendar): prevent to return the same user twice in ldap groups 2024-10-29 17:14:25 +01:00
Hivert Quentin 1c611a0a4a chore(js/css): update generated files 2024-10-23 01:00:36 -04:00
smizrahi f2ba6870d5 feat(core): Add new SOGoURLCreateAccount option to add a create account link below login form 2024-10-22 16:03:50 +02:00
smizrahi 253d14cfce fix(core): Specify application name in WORequest to avoid computing app name in SOPE. Sometimes the app name is wrongly defined due to invalid URL calls. 2024-10-22 09:46:00 +02:00
smizrahi b3c77a0e00 fix(mail): Add 'Return-Receipt-To' header for mail receipt 2024-10-16 09:44:53 +02:00
29 changed files with 558 additions and 35 deletions

No files matched your search

@@ -815,6 +815,8 @@ Obiously, if your users can connect without specifying a domain, let this parame
|S |SOGoDomainAllowed
|Parameter used to define which domains SOGo should allowed during a connection request. This parameter is an array of strings.
|S |SOGoURLCreateAccount
|Add a link below the login form and set the link using the value of this setting.
|S |SOGoPasswordRecoveryEnabled
|Boolean enable password recovery with secret question or secondary e-mail. Default value is `NO`.
@@ -1676,6 +1678,9 @@ URL could be set to something like:
See the "EMail reminders" section in this document for more information.
|S |SOGoDisableMailCleaning
|Parameter used to disable the feature 'remove mails older than X days' introduced in 5.12. Default value is `NO`.
|S |SOGoDisableOrganizerEventCheck
|Parameter used to disable organizer's calendar event check
+17 -19
View File
@@ -1130,28 +1130,26 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
delta = [masterEndDate timeIntervalSinceDate: [master startDate]];
recurrenceIdRange = [NGCalendarDateRange calendarDateRangeWithStartDate: recurrenceId
endDate: [recurrenceId dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds: delta]];
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange])
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];
}
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange] && recordIndex != -1)
{
// The recurrence exception intersects with the date range;
// find the occurence and replace it with the new record
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId inArray: ma];
if (recordIndex > -1)
{
if ([dateRange containsDate: [component startDate]] ||
(endDate && [dateRange containsDate: endDate]))
{
// We must pass nil to :container here in order to avoid re-entrancy issues.
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil nameInContainer: nil]];
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
}
else
// The range doesn't cover the exception; remove it from the records
[ma removeObjectAtIndex: recordIndex];
}
else
[self errorWithFormat:
@"missing exception record for recurrence-id %@ (uid %@)",
recurrenceId, [component uid]];
if ([dateRange containsDate: [component startDate]] ||
(endDate && [dateRange containsDate: endDate]))
{
// We must pass nil to :container here in order to avoid re-entrancy issues.
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil nameInContainer: nil]];
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
}
else
// The range doesn't cover the exception; remove it from the records
[ma removeObjectAtIndex: recordIndex];
}
else
{
+10 -4
View File
@@ -291,6 +291,7 @@ static NSString *userAgent = nil;
{
[headers setObject: @"true" forKey: @"receipt"];
[headers setObject: receipt forKey: @"Disposition-Notification-To"];
[headers setObject: receipt forKey: @"Return-Receipt-To"];
}
else
{
@@ -302,12 +303,14 @@ static NSString *userAgent = nil;
if (pureSender)
{
[headers setObject: pureSender forKey: @"Disposition-Notification-To"];
[headers setObject: pureSender forKey: @"Return-Receipt-To"];
}
}
else
{
[headers removeObjectForKey: @"receipt"];
[headers removeObjectForKey: @"Disposition-Notification-To"];
[headers removeObjectForKey: @"Return-Receipt-To"];
}
}
}
@@ -990,7 +993,6 @@ static NSString *userAgent = nil;
[self _fileAttachmentsFromPart: [m body] onlyImages: onlyImages];
}
//
//
//
@@ -1019,7 +1021,7 @@ static NSString *userAgent = nil;
addresses = [NSMutableArray array];
[self _addEMailsOfAddresses: [sourceEnvelope from] toArray: addresses];
if ([addresses count])
if ([addresses count] > 0)
[info setObject: [addresses objectAtIndex: 0] forKey: @"from"];
addresses = [NSMutableArray array];
[self _addEMailsOfAddresses: [sourceEnvelope to] toArray: addresses];
@@ -1035,15 +1037,17 @@ static NSString *userAgent = nil;
addresses = [NSMutableArray array];
[self _addEMailsOfAddresses: [sourceEnvelope replyTo] toArray: addresses];
if ([addresses count] > 0)
[info setObject: addresses forKey: @"replyTo"];
[info setObject: [addresses objectAtIndex: 0] forKey: @"replyTo"];
h = [sourceMail mailHeaders];
priority = [h objectForKey: @"x-priority"];
if ([priority isNotEmpty] && [priority isKindOfClass: [NSString class]])
[info setObject: (NSString*)priority forKey: @"X-Priority"];
receipt = [h objectForKey: @"disposition-notification-to"];
if ([receipt isNotEmpty] && [receipt isKindOfClass: [NSString class]])
if ([receipt isNotEmpty] && [receipt isKindOfClass: [NSString class]]) {
[info setObject: (NSString*)receipt forKey: @"Disposition-Notification-To"];
[info setObject: (NSString*)receipt forKey: @"Return-Receipt-To"];
}
ud = [[context activeUser] userDefaults];
@@ -1893,6 +1897,8 @@ static NSString *userAgent = nil;
[map setObject: s forKey: @"X-Priority"];
if ([(s = [headers objectForKey: @"Disposition-Notification-To"]) length] > 0)
[map setObject: s forKey: @"Disposition-Notification-To"];
if ([(s = [headers objectForKey: @"Return-Receipt-To"]) length] > 0)
[map setObject: s forKey: @"Return-Receipt-To"];
[self _addHeaders: _headers toHeaderMap: map];
+1
View File
@@ -104,6 +104,7 @@ typedef enum {
- (NSArray *) toManyRelationshipKeysWithNamespaces: (BOOL) withNSs;
- (NSArray *) allFolderPaths: (SOGoMailListingMode) theListingMode;
- (NSArray *) allFolderPaths: (SOGoMailListingMode) theListingMode onlyRoot: (BOOL) onlyRoot;
- (NSArray *) allFoldersMetadata: (SOGoMailListingMode) theListingMode;
- (NSDictionary *) imapFolderGUIDs;
+27 -9
View File
@@ -378,14 +378,21 @@ static NSString *inboxFolderName = @"INBOX";
return folders;
}
//
//
//
- (NSArray *) allFolderPaths: (SOGoMailListingMode) theListingMode
- (NSArray *) allFolderPaths: (SOGoMailListingMode) theListingMode
{
NSMutableArray *folderPaths, *namespaces;
return [self allFolderPaths: theListingMode onlyRoot: NO];
}
//
//
//
- (NSArray *) allFolderPaths: (SOGoMailListingMode) theListingMode onlyRoot: (BOOL) onlyRoot
{
NSMutableArray *folderPaths, *namespaces, *filteredFolders;
NSArray *folders, *mainFolders;
NSString *namespace;
NSString *folder;
NSUInteger slashCount;
BOOL subscribedOnly;
int count, max;
@@ -401,10 +408,10 @@ static NSString *inboxFolderName = @"INBOX";
onlySubscribedFolders: YES];
max = [folders count];
for (count = 0; count < max; count++)
{
[subscribedFolders setObject: [NSNull null]
forKey: [folders objectAtIndex: count]];
}
{
[subscribedFolders setObject: [NSNull null]
forKey: [folders objectAtIndex: count]];
}
[[self imap4Connection] flushFolderHierarchyCache];
}
@@ -418,6 +425,17 @@ static NSString *inboxFolderName = @"INBOX";
nil] stringsWithFormat: @"/%@"];
folders = [[self imap4Connection] allFoldersForURL: [self imap4URL]
onlySubscribedFolders: subscribedOnly];
if (onlyRoot) {
filteredFolders = [[NSMutableArray alloc] init];
for (folder in folders) {
slashCount = [[folder componentsSeparatedByString:@"/"] count] - 1;
if (slashCount <= 1) {
[filteredFolders addObject: folder];
}
}
folders = [NSArray arrayWithArray: filteredFolders];
[filteredFolders release];
}
folderPaths = [folders mutableCopy];
[folderPaths autorelease];
+16 -1
View File
@@ -2306,7 +2306,7 @@ _makeLDAPChanges (NGLdapConnection *ldapConnection,
- (NSArray *) membersForGroupWithUID: (NSString *) uid
{
NSMutableArray *dns, *uids;
NSMutableArray *dns, *uids, *userLogins;
NSString *dn, *login;
SOGoUserManager *um;
NSDictionary *d, *contactInfos;
@@ -2327,6 +2327,7 @@ _makeLDAPChanges (NGLdapConnection *ldapConnection,
members = [NSMutableArray new];
uids = [NSMutableArray array];
dns = [NSMutableArray array];
userLogins = [NSMutableArray array];
// We check if it's a static group
// Fetch "members" - we get DNs
@@ -2358,6 +2359,13 @@ _makeLDAPChanges (NGLdapConnection *ldapConnection,
pool = [NSAutoreleasePool new];
dn = [dns objectAtIndex: i];
login = [um getLoginForDN: [dn lowercaseString]];
if([userLogins containsObject: login])
{
[pool release];
continue; //user alrady fetch
}
if(login != nil)
[userLogins addObject: login];
user = [SOGoUser userWithLogin: login roles: nil];
if (user)
{
@@ -2385,6 +2393,13 @@ _makeLDAPChanges (NGLdapConnection *ldapConnection,
{
pool = [NSAutoreleasePool new];
login = [uids objectAtIndex: i];
if([userLogins containsObject: login])
{
[pool release];
continue; //user alrady fetch
}
if(login != nil)
[userLogins addObject: login];
user = [SOGoUser userWithLogin: login roles: nil];
if (user)
{
+4
View File
@@ -140,6 +140,10 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
- (BOOL)isURLEncryptionEnabled;
- (NSString *)urlEncryptionPassphrase;
- (NSString *)urlCreateAccount;
- (BOOL)disableMailCleaning;
@end
#endif /* SOGOSYSTEMDEFAULTS_H */
+10
View File
@@ -928,4 +928,14 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return disableExport;
}
- (NSString *)urlCreateAccount
{
return [self stringForKey: @"SOGoURLCreateAccount"];
}
- (BOOL) disableMailCleaning
{
return [self boolForKey: @"SOGoDisableMailCleaning"];
}
@end
+4
View File
@@ -267,4 +267,8 @@
return ret;
}
- (NSString *) applicationName {
return @"SOGo";
}
@end
@@ -514,3 +514,18 @@
/* Hotkey to forward to a message */
"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";
@@ -514,3 +514,18 @@
/* Hotkey to forward to a message */
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Nettoyer le dossier";
"Clean mailbox" = "Nettoyer la boite mail";
"Delete permanently (do not use trash)" = "Supprimer définitivement (ne pas utiliser la corbeille)";
"Apply to subfolders" = "Appliquer aux sous-dossiers";
"Delete e-mails older than" = "Supprimer les e-mails plus vieux de";
"3 months" = "3 mois";
"6 months" = "6 mois";
"9 months" = "9 mois";
"1 year" = "1 an";
"Custom" = "Personnalisé";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "Vous êtes sur le point de supprimer définitivement certains messages. Êtes-vous certain de vouloir effectuer cette action ?";
"Apply" = "Appliquer";
"%{0} message(s) deleted" = "%{0} message(s) supprimés";
+2
View File
@@ -132,6 +132,8 @@
drafts = [account draftsFolderInContext: context];
newMail = [drafts newDraft];
[newMail fetchMailForEditing: co];
if ([co isInTemplatesFolder])
[newMail save];
[newMail storeInfo];
accountName = [account nameInContainer];
+124
View File
@@ -21,6 +21,7 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <Foundation/Foundation.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest.h>
@@ -46,6 +47,8 @@
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserSettings.h>
#import <EOControl/EOQualifier.h>
#import "UIxMailFolderActions.h"
@implementation UIxMailFolderActions
@@ -1298,4 +1301,125 @@
return [self _markMessagesAsJunkOrNotJunk: NO];
}
- (BOOL)isDateStringValid: (NSString *)dateString {
NSString *dateRegex = @"^\\d{4}-\\d{2}-\\d{2}$";
NSPredicate *dateTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", dateRegex];
return [dateTest evaluateWithObject:dateString];
}
- (void) cleanFolderWithFolder: (SOGoMailFolder *)folder
withQualifier: (EOQualifier *)qualifier
recursive: (BOOL)isRecursive
withTrashFolder: (BOOL)useTrashFolder
exception: (NSException **)exception
counter: (NSUInteger *)counter {
NSArray *results, *subfolders;
NSUInteger i;
SOGoMailFolder *newFolder;
NSString *folderName;
NSException *e;
results = [folder fetchUIDsMatchingQualifier: qualifier
sortOrdering: @"REVERSE DATE"
threaded: NO];
if (results && [results count] > 0) {
e = [folder deleteUIDs: results
useTrashFolder: &useTrashFolder
inContext: [self context]];
[folder expunge];
[self logWithFormat: @"Removed %d messages in %@ (%@)", [results count], [folder nameInContainer], results];
*counter += [results count];
if (e) {
[self errorWithFormat: @"Error while cleaning mailbox : %@", e];
*exception = e;
}
}
if (isRecursive) {
subfolders = [folder subfolders];
for (i = 0 ; i < [subfolders count] ; i++) {
folderName = [NSString stringWithFormat:@"%@/%@", [folder nameInContainer], [subfolders objectAtIndex: i]];
newFolder = [[SOGoMailFolder alloc] initWithName: folderName inContainer: [folder container]];
[self cleanFolderWithFolder: newFolder
withQualifier: qualifier
recursive: isRecursive
withTrashFolder: useTrashFolder
exception: exception
counter: counter];
[newFolder release];
}
}
}
- (WOResponse *) cleanMailboxAction
{
NSDictionary *jsonRequest, *jsonResponse;
WORequest *request;
NSString *searchString, *folderName;
EOQualifier *searchQualifier;
BOOL isRecursive, useTrashFolder;
NSException *exception;
SOGoMailFolder *folder;
SOGoMailAccount *account;
NSUInteger i, counter;
NSArray *folderNames;
request = [[self context] request];
jsonRequest = [[request contentAsString] objectFromJSONString];
if ([[SOGoSystemDefaults sharedSystemDefaults] disableMailCleaning])
return [self responseWithStatus: 401];
if (![self isDateStringValid: [jsonRequest objectForKey: @"date"]]) {
[self errorWithFormat: @"Error while cleaning mailbox, invalid date : %@", [jsonRequest objectForKey: @"date"]];
return [self responseWithStatus: 502];
}
searchString = [NSString stringWithFormat: @"(NOT (flags = 'deleted') AND (DATE <= (NSCalendarDate)\"%@\"))", [jsonRequest objectForKey: @"date"]];
searchQualifier = [EOQualifier qualifierWithQualifierFormat: searchString];
isRecursive = [[jsonRequest objectForKey: @"applyToSubfolders"] boolValue];
useTrashFolder = ![[jsonRequest objectForKey: @"permanentlyDelete"] boolValue];
counter = 0;
exception = nil;
if ([[self clientObject] isKindOfClass: [SOGoMailFolder class]]) {
folder = [self clientObject];
[self cleanFolderWithFolder: folder
withQualifier: searchQualifier
recursive: isRecursive
withTrashFolder: useTrashFolder
exception: &exception
counter: &counter];
} else if ([[self clientObject] isKindOfClass: [SOGoMailAccount class]]) {
account = [self clientObject];
folderNames = [account allFolderPaths: SOGoMailStandardListing onlyRoot: YES];
for (i = 0 ; i < [folderNames count] ; i ++) {
folderName = [folderNames objectAtIndex: i];
if ([folderName hasPrefix:@"/"]) {
folderName = [folderName substringFromIndex:1];
}
folder = [account folderWithTraversal: folderName andClassName: nil];
// Disable clean for trash folder
if (![folderName isEqualToString: [account trashFolderNameInContext: [self context]]])
[self cleanFolderWithFolder: folder
withQualifier: searchQualifier
recursive: isRecursive
withTrashFolder: useTrashFolder
exception: &exception
counter: &counter];
}
[[account imap4Connection] flushMailCaches];
}
if (exception) {
return [self responseWithStatus: 500];
}
jsonResponse = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: counter]
forKey: @"nbMessageDeleted"];
return [self responseWithStatus: 200 andJSONRepresentation: jsonResponse];
}
@end
+11
View File
@@ -611,6 +611,17 @@
return result;
}
- (BOOL) isCleanMailboxEnabled {
BOOL result;
SOGoSystemDefaults *sd;
sd = [SOGoSystemDefaults sharedSystemDefaults];
result = ![sd disableMailCleaning];
return result;
}
@end /* UIxMailMainFrame */
@interface UIxMailFolderTemplate : UIxComponent
+10
View File
@@ -49,6 +49,11 @@
actionClass = "UIxMailFolderActions";
actionName = "expunge";
};
cleanMailbox = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
actionName = "cleanMailbox";
};
createFolder = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
@@ -417,6 +422,11 @@
protectedBy = "View";
pageName = "UIxMailUserDelegationEditor";
};
cleanMailbox = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
actionName = "cleanMailbox";
};
addDelegate = {
protectedBy = "View";
actionClass = "UIxMailAccountActions";
@@ -6,6 +6,7 @@
"Domain" = "Domain";
"Remember username" = "Remember username";
"Connect" = "Connect";
"Create an account" = "Create an account";
/* Appears while authentication is in progress */
"Authenticating" = "Authenticating";
@@ -6,6 +6,7 @@
"Domain" = "Domaine";
"Remember username" = "Se souvenir de moi";
"Connect" = "Connexion";
"Create an account" = "Créer un compte";
/* Appears while authentication is in progress */
"Authenticating" = "Authentification en cours";
+12
View File
@@ -1060,4 +1060,16 @@ static const NSString *kJwtKey = @"jwt";
return [[SOGoAdmin sharedInstance] getMotd] && [[[SOGoAdmin sharedInstance] getMotd] length] > 1;
}
- (BOOL) hasUrlCreateAccount
{
return ([[SOGoSystemDefaults sharedSystemDefaults]
urlCreateAccount] != nil);
}
- (NSString *) urlCreateAccount
{
return [[SOGoSystemDefaults sharedSystemDefaults]
urlCreateAccount];
}
@end /* SOGoRootPage */
+1
View File
@@ -350,6 +350,7 @@ static NSArray *tasksFields = nil;
//NSLog(@"***[UIxCalListingActions _fixDates:] %@ = %@ (%i)", aDateField, aDate, daylightOffset);
if (daylightOffset)
{
[self logWithFormat: @"Changing date (aDate '%@'), (startDate '%@'), (daylightOffset %d)", aDate, startDate, daylightOffset];
// If it is the end date and allday, we need to remove the offset
if ([fields[count * 2] isEqualToString: @"endDate"] && [[theRecord objectForKey: @"c_isallday"] boolValue] && daylightOffset > 0)
aDate = [aDate dateByAddingYears: 0 months: 0 days: 0 hours: 0
@@ -632,4 +632,87 @@
</md-dialog-actions>
</md-dialog>
</script>
<!-- Remove old emails -->
<script type="text/ng-template" id="cleanMailbox">
<md-dialog flex="50" flex-sm="80" flex-xs="100">
<!-- Toolbar -->
<md-toolbar>
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">delete</md-icon>
<div class="pseudo-input-container md-flex" ng-if="::!dialogCtrl.isMailbox">
<var:string label:value="Clean folder"/>
</div>
<div class="pseudo-input-container md-flex" ng-if="::dialogCtrl.isMailbox">
<var:string label:value="Clean mailbox"/>
</div>
<md-button class="md-icon-button" ng-click="dialogCtrl.closeDialog()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<!-- Dialog Content -->
<md-dialog-content class="md-dialog-content">
<div class="md-dialog-content">
<h4>
{{ dialogCtrl.name }}
</h4>
<md-input-container class="md-block">
<md-checkbox ng-model="dialogCtrl.form.permanentlyDelete" label:aria-label="Delete permanently (do not use trash)">
<var:string label:value="Delete permanently (do not use trash)"/>
</md-checkbox>
</md-input-container>
<md-input-container class="md-block">
<md-checkbox ng-model="dialogCtrl.form.applyToSubfolders" label:aria-label="Apply to subfolders">
<var:string label:value="Apply to subfolders"/>
</md-checkbox>
</md-input-container>
<md-input-container class="md-block">
<label><var:string label:value="Delete e-mails older than"/></label>
<md-select ng-model="dialogCtrl.form.filterDuration">
<md-option value="3m"><var:string label:value="3 months"/></md-option>
<md-option value="6m"><var:string label:value="6 months"/></md-option>
<md-option value="9m"><var:string label:value="9 months"/></md-option>
<md-option value="1y"><var:string label:value="1 year"/></md-option>
<md-option value="custom"><var:string label:value="Custom"/></md-option>
</md-select>
</md-input-container>
<md-input-container class="md-block" ng-show="['custom'].indexOf(dialogCtrl.form.filterDuration) != -1">
<label><var:string label:value="Date"/></label>
<md-datepicker class="md-text"
ng-model="dialogCtrl.form.filterDurationDate"
md-hide-icons="calendar"
md-max-date="dialogCtrl.maxDate"
ng-change="dialogCtrl.mainController.changeDate()">
</md-datepicker>
</md-input-container>
<md-input-container class="md-block" ng-show="dialogCtrl.isWarningDisplayed()">
<md-checkbox ng-model="dialogCtrl.form.confirmDelete" label:aria-label="You are about to permanently delete some messages. Are you sure you want to proceed with this action?">
<span class="clean-mailbox-warn"><var:string label:value="You are about to permanently delete some messages. Are you sure you want to proceed with this action?" /></span>
</md-checkbox>
</md-input-container>
</div>
</md-dialog-content>
<!-- Dialog Actions -->
<md-dialog-actions>
<md-button class="md-warn" ng-click="dialogCtrl.closeDialog()">
<var:string label:value="Cancel" />
</md-button>
<div class="sg-progress-linear-bottom"
ng-show="dialogCtrl.isLoading()">
<md-progress-linear class="md-accent"
md-mode="indeterminate"><!-- progress --></md-progress-linear>
</div>
<md-button class="md-primary" ng-disabled="dialogCtrl.isApplyDisabled()" ng-click="dialogCtrl.apply()">
<var:string label:value="Apply" />
</md-button>
</md-dialog-actions>
</md-dialog>
</script>
</container>
@@ -69,6 +69,13 @@
<var:string label:value="New Folder..."/>
</md-button>
</md-menu-item>
<var:if condition="isCleanMailboxEnabled">
<md-menu-item>
<md-button type="button" ng-click="app.showCleanMailboxPanel(null, account)">
<var:string label:value="Clean mailbox"/>...
</md-button>
</md-menu-item>
</var:if>
<md-menu-item ng-show="::account.id == 0">
<md-button
label:aria-label="Search"
@@ -179,6 +186,13 @@
<var:string label:value="Compact"/>
</md-button>
</md-menu-item>
<var:if condition="isCleanMailboxEnabled">
<md-menu-item ng-show="::($menuCtrl.folder.type != 'trash')">
<md-button type="button" ng-click="$menuCtrl.cleanMailbox()">
<var:string label:value="Clean folder"/>...
</md-button>
</md-menu-item>
</var:if>
<md-menu-item ng-show="::$menuCtrl.folder.$isEditable">
<md-button type="button" ng-click="$menuCtrl.confirmDelete()">
<var:string label:value="Delete"/>
+5
View File
@@ -106,6 +106,11 @@
<var:string label:value="Remember username"/>
</md-switch>
</div>
<var:if condition="hasUrlCreateAccount">
<div layout="row" layout-align="center center">
<a var:href="urlCreateAccount" target="_blank" class="create-account-link"><var:string label:value="Create an account"/></a>
</div>
</var:if>
</div>
<!-- Password recovery -->
+1 -1
View File
@@ -1,2 +1,2 @@
@charset "UTF-8";.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.sg-hide{opacity:0}@-moz-document url-prefix(){[layout-fill]{margin:0;width:100%;min-height:100%;height:100%}}[flex-order]{-webkit-box-ordinal-group:1;-webkit-order:0;order:0}[flex-order="-20"]{-webkit-box-ordinal-group:-19;-webkit-order:-20;order:-20}[flex-order="-19"]{-webkit-box-ordinal-group:-18;-webkit-order:-19;order:-19}[flex-order="-18"]{-webkit-box-ordinal-group:-17;-webkit-order:-18;order:-18}[flex-order="-17"]{-webkit-box-ordinal-group:-16;-webkit-order:-17;order:-17}[flex-order="-16"]{-webkit-box-ordinal-group:-15;-webkit-order:-16;order:-16}[flex-order="-15"]{-webkit-box-ordinal-group:-14;-webkit-order:-15;order:-15}[flex-order="-14"]{-webkit-box-ordinal-group:-13;-webkit-order:-14;order:-14}[flex-order="-13"]{-webkit-box-ordinal-group:-12;-webkit-order:-13;order:-13}[flex-order="-12"]{-webkit-box-ordinal-group:-11;-webkit-order:-12;order:-12}[flex-order="-11"]{-webkit-box-ordinal-group:-10;-webkit-order:-11;order:-11}[flex-order="-10"]{-webkit-box-ordinal-group:-9;-webkit-order:-10;order:-10}[flex-order="-9"]{-webkit-box-ordinal-group:-8;-webkit-order:-9;order:-9}[flex-order="-8"]{-webkit-box-ordinal-group:-7;-webkit-order:-8;order:-8}[flex-order="-7"]{-webkit-box-ordinal-group:-6;-webkit-order:-7;order:-7}[flex-order="-6"]{-webkit-box-ordinal-group:-5;-webkit-order:-6;order:-6}[flex-order="-5"]{-webkit-box-ordinal-group:-4;-webkit-order:-5;order:-5}[flex-order="-4"]{-webkit-box-ordinal-group:-3;-webkit-order:-4;order:-4}[flex-order="-3"]{-webkit-box-ordinal-group:-2;-webkit-order:-3;order:-3}[flex-order="-2"]{-webkit-box-ordinal-group:-1;-webkit-order:-2;order:-2}[flex-order="-1"]{-webkit-box-ordinal-group:0;-webkit-order:-1;order:-1}[flex-order="0"]{-webkit-box-ordinal-group:1;-webkit-order:0;order:0}[flex-order="1"]{-webkit-box-ordinal-group:2;-webkit-order:1;order:1}[flex-order="2"]{-webkit-box-ordinal-group:3;-webkit-order:2;order:2}[flex-order="3"]{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}[flex-order="4"]{-webkit-box-ordinal-group:5;-webkit-order:4;order:4}[flex-order="5"]{-webkit-box-ordinal-group:6;-webkit-order:5;order:5}[flex-order="6"]{-webkit-box-ordinal-group:7;-webkit-order:6;order:6}[flex-order="7"]{-webkit-box-ordinal-group:8;-webkit-order:7;order:7}[flex-order="8"]{-webkit-box-ordinal-group:9;-webkit-order:8;order:8}[flex-order="9"]{-webkit-box-ordinal-group:10;-webkit-order:9;order:9}[flex-order="10"]{-webkit-box-ordinal-group:11;-webkit-order:10;order:10}[flex-order="11"]{-webkit-box-ordinal-group:12;-webkit-order:11;order:11}[flex-order="12"]{-webkit-box-ordinal-group:13;-webkit-order:12;order:12}[flex-order="13"]{-webkit-box-ordinal-group:14;-webkit-order:13;order:13}[flex-order="14"]{-webkit-box-ordinal-group:15;-webkit-order:14;order:14}[flex-order="15"]{-webkit-box-ordinal-group:16;-webkit-order:15;order:15}[flex-order="16"]{-webkit-box-ordinal-group:17;-webkit-order:16;order:16}[flex-order="17"]{-webkit-box-ordinal-group:18;-webkit-order:17;order:17}[flex-order="18"]{-webkit-box-ordinal-group:19;-webkit-order:18;order:18}[flex-order="19"]{-webkit-box-ordinal-group:20;-webkit-order:19;order:19}[flex-order="20"]{-webkit-box-ordinal-group:21;-webkit-order:20;order:20}[flex-offset="0"]{margin-left:0}[flex-offset="5"]{margin-left:5%}[flex-offset="10"]{margin-left:10%}[flex-offset="15"]{margin-left:15%}[flex-offset="20"]{margin-left:20%}[flex-offset="25"]{margin-left:25%}[flex-offset="30"]{margin-left:30%}[flex-offset="35"]{margin-left:35%}[flex-offset="40"]{margin-left:40%}[flex-offset="45"]{margin-left:45%}[flex-offset="50"]{margin-left:50%}[flex-offset="55"]{margin-left:55%}[flex-offset="60"]{margin-left:60%}[flex-offset="65"]{margin-left:65%}[flex-offset="70"]{margin-left:70%}[flex-offset="75"]{margin-left:75%}[flex-offset="80"]{margin-left:80%}[flex-offset="85"]{margin-left:85%}[flex-offset="90"]{margin-left:90%}[flex-offset="95"]{margin-left:95%}[flex-offset="33"]{margin-left:33.3333333333%}[flex-offset="66"]{margin-left:66.6666666667%}[layout-align="start stretch"],[layout-align]{-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:stretch;align-content:stretch;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch}[layout-align="start center"],[layout-align="start end"],[layout-align="start start"],[layout-align="start stretch"],[layout-align=start]{-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}[layout-align="center center"],[layout-align="center end"],[layout-align="center start"],[layout-align="center stretch"],[layout-align=center]{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}[layout-align="end center"],[layout-align="end end"],[layout-align="end start"],[layout-align="end stretch"],[layout-align=end]{-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}[layout-align="spacLine truncated
@charset "UTF-8";.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.sg-hide{opacity:0}@-moz-document url-prefix(){[layout-fill]{margin:0;width:100%;min-height:100%;height:100%}}[flex-order]{-webkit-box-ordinal-group:1;-webkit-order:0;order:0}[flex-order="-20"]{-webkit-box-ordinal-group:-19;-webkit-order:-20;order:-20}[flex-order="-19"]{-webkit-box-ordinal-group:-18;-webkit-order:-19;order:-19}[flex-order="-18"]{-webkit-box-ordinal-group:-17;-webkit-order:-18;order:-18}[flex-order="-17"]{-webkit-box-ordinal-group:-16;-webkit-order:-17;order:-17}[flex-order="-16"]{-webkit-box-ordinal-group:-15;-webkit-order:-16;order:-16}[flex-order="-15"]{-webkit-box-ordinal-group:-14;-webkit-order:-15;order:-15}[flex-order="-14"]{-webkit-box-ordinal-group:-13;-webkit-order:-14;order:-14}[flex-order="-13"]{-webkit-box-ordinal-group:-12;-webkit-order:-13;order:-13}[flex-order="-12"]{-webkit-box-ordinal-group:-11;-webkit-order:-12;order:-12}[flex-order="-11"]{-webkit-box-ordinal-group:-10;-webkit-order:-11;order:-11}[flex-order="-10"]{-webkit-box-ordinal-group:-9;-webkit-order:-10;order:-10}[flex-order="-9"]{-webkit-box-ordinal-group:-8;-webkit-order:-9;order:-9}[flex-order="-8"]{-webkit-box-ordinal-group:-7;-webkit-order:-8;order:-8}[flex-order="-7"]{-webkit-box-ordinal-group:-6;-webkit-order:-7;order:-7}[flex-order="-6"]{-webkit-box-ordinal-group:-5;-webkit-order:-6;order:-6}[flex-order="-5"]{-webkit-box-ordinal-group:-4;-webkit-order:-5;order:-5}[flex-order="-4"]{-webkit-box-ordinal-group:-3;-webkit-order:-4;order:-4}[flex-order="-3"]{-webkit-box-ordinal-group:-2;-webkit-order:-3;order:-3}[flex-order="-2"]{-webkit-box-ordinal-group:-1;-webkit-order:-2;order:-2}[flex-order="-1"]{-webkit-box-ordinal-group:0;-webkit-order:-1;order:-1}[flex-order="0"]{-webkit-box-ordinal-group:1;-webkit-order:0;order:0}[flex-order="1"]{-webkit-box-ordinal-group:2;-webkit-order:1;order:1}[flex-order="2"]{-webkit-box-ordinal-group:3;-webkit-order:2;order:2}[flex-order="3"]{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}[flex-order="4"]{-webkit-box-ordinal-group:5;-webkit-order:4;order:4}[flex-order="5"]{-webkit-box-ordinal-group:6;-webkit-order:5;order:5}[flex-order="6"]{-webkit-box-ordinal-group:7;-webkit-order:6;order:6}[flex-order="7"]{-webkit-box-ordinal-group:8;-webkit-order:7;order:7}[flex-order="8"]{-webkit-box-ordinal-group:9;-webkit-order:8;order:8}[flex-order="9"]{-webkit-box-ordinal-group:10;-webkit-order:9;order:9}[flex-order="10"]{-webkit-box-ordinal-group:11;-webkit-order:10;order:10}[flex-order="11"]{-webkit-box-ordinal-group:12;-webkit-order:11;order:11}[flex-order="12"]{-webkit-box-ordinal-group:13;-webkit-order:12;order:12}[flex-order="13"]{-webkit-box-ordinal-group:14;-webkit-order:13;order:13}[flex-order="14"]{-webkit-box-ordinal-group:15;-webkit-order:14;order:14}[flex-order="15"]{-webkit-box-ordinal-group:16;-webkit-order:15;order:15}[flex-order="16"]{-webkit-box-ordinal-group:17;-webkit-order:16;order:16}[flex-order="17"]{-webkit-box-ordinal-group:18;-webkit-order:17;order:17}[flex-order="18"]{-webkit-box-ordinal-group:19;-webkit-order:18;order:18}[flex-order="19"]{-webkit-box-ordinal-group:20;-webkit-order:19;order:19}[flex-order="20"]{-webkit-box-ordinal-group:21;-webkit-order:20;order:20}[flex-offset="0"]{margin-left:0}[flex-offset="5"]{margin-left:5%}[flex-offset="10"]{margin-left:10%}[flex-offset="15"]{margin-left:15%}[flex-offset="20"]{margin-left:20%}[flex-offset="25"]{margin-left:25%}[flex-offset="30"]{margin-left:30%}[flex-offset="35"]{margin-left:35%}[flex-offset="40"]{margin-left:40%}[flex-offset="45"]{margin-left:45%}[flex-offset="50"]{margin-left:50%}[flex-offset="55"]{margin-left:55%}[flex-offset="60"]{margin-left:60%}[flex-offset="65"]{margin-left:65%}[flex-offset="70"]{margin-left:70%}[flex-offset="75"]{margin-left:75%}[flex-offset="80"]{margin-left:80%}[flex-offset="85"]{margin-left:85%}[flex-offset="90"]{margin-left:90%}[flex-offset="95"]{margin-left:95%}[flex-offset="33"]{margin-left:33.3333333333%}[flex-offset="66"]{margin-left:66.6666666667%}[layout-align="start stretch"],[layout-align]{-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:stretch;align-content:stretch;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch}[layout-align="start center"],[layout-align="start end"],[layout-align="start start"],[layout-align="start stretch"],[layout-align=start]{-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}[layout-align="center center"],[layout-align="center end"],[layout-align="center start"],[layout-align="center stretch"],[layout-align=center]{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}[layout-align="end center"],[layout-align="end end"],[layout-align="end start"],[layout-align="end stretch"],[layout-align=end]{-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}[layout-align="spacLine truncated
/*# sourceMappingURL=styles.css.map */
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["css/styles.css"],"names":[],"mappings":"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 truncated
{"version":3,"sources":["css/styles.css"],"names":[],"mappings":"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 truncated
@@ -1312,4 +1312,21 @@
Mailbox.prototype.getHighlightWords = function () {
return this.$highlightWords;
};
/**
* @function cleanMailbox
* @memberof Mailbox.prototype
* @desc Cleans up the mailbox by applying the specified parameters.
* This can include operations such as moving emails to trash,
* filtering emails based on a duration, and applying actions to subfolders.
* @param {Object} parameters - An object containing the parameters for cleaning the mailbox.
* @param {boolean} [parameters.applyToSubfolders=false] - Whether to apply the cleaning operation to subfolders.
* @param {boolean} [parameters.moveToTrash=false] - Whether to move the emails to the trash folder.
* @param {string|null} [parameters.filterDuration=null] - A duration filter (e.g., "3m", "6m") to select emails older than the specified duration.
* @returns {Promise} A promise that resolves when the cleaning operation is completed, or rejects with an error if the operation fails.
*/
Mailbox.prototype.cleanMailbox = function (parameters) {
return parameters.folders.length > 0 ? Mailbox.$$resource.post(this.id.split("/")[0], 'cleanMailbox', parameters) : Mailbox.$$resource.post(this.id, 'cleanMailbox', parameters);
};
})();
@@ -53,6 +53,10 @@
$rootScope.$on('resetMailAdvancedSearchPanel', function () {
vm.reset();
});
$rootScope.$on('showCleanMailboxPanel', function (e, d) {
vm.showCleanMailboxPanel(d.folder, d.account);
});
};
@@ -447,6 +451,128 @@
});
};
this.showCleanMailboxPanel = function (folder, account) {
// Close sidenav on small devices
if (!$mdMedia(sgConstant['gt-md']))
$mdSidenav('left').close();
$mdDialog.show({
template: document.getElementById('cleanMailbox').innerHTML,
parent: angular.element(document.body),
controller: function () {
var dialogCtrl = this;
this.$onInit = function () {
this.mainController = vm;
this.folder = folder;
this.isMailbox = (folder ? false : true);
this.name = folder ? folder.$displayName : account.name;
this.loading = false;
this.date = null;
this.form = {
filterDuration: "3m",
permanentlyDelete: false,
confirmDelete: false,
filterDurationDate: null
};
var today = new Date();
var maxDate = new Date(today);
maxDate.setMonth(today.getMonth() - 3);
this.maxDate = maxDate;
};
dialogCtrl.closeDialog = function () {
$mdDialog.hide();
};
dialogCtrl.isLoading = function () {
return this.loading;
}
dialogCtrl.isWarningDisplayed = function () {
return (this.form && this.form.permanentlyDelete);
}
dialogCtrl.isApplyDisabled = function () {
return !(!this.loading
&& (!this.form.permanentlyDelete || (this.form.permanentlyDelete && this.form.confirmDelete))
&& (this.form.filterDuration != 'custom' || (this.form.filterDuration == 'custom' && this.form.filterDurationDate))
);
}
dialogCtrl.apply = function () {
var folders = [];
var i;
if (account) {
for (i = 0; i < account.$mailboxes.length ; i++) {
folders.push(account.$mailboxes[i].id);
}
this.folder = account.$mailboxes[0];
}
var date = '';
var durationMonth = 12;
var date = new Date();
switch (this.form.filterDuration) {
case '3m':
durationMonth = 3;
date.setMonth(date.getMonth() - durationMonth);
break;
case '6m':
durationMonth = 6;
date.setMonth(date.getMonth() - durationMonth);
break;
case '9m':
durationMonth = 9;
date.setMonth(date.getMonth() - durationMonth);
break;
case '1y':
durationMonth = 12;
date.setMonth(date.getMonth() - durationMonth);
break;
case 'custom':
date = this.form.filterDurationDate;
break;
}
var year = date.getFullYear();
var month = String(date.getMonth() + 1).padStart(2, '0');
var day = String(date.getDate()).padStart(2, '0');
this.date = `${year}-${month}-${day}`;
this.folder.cleanMailbox({
'applyToSubfolders': (this.form && this.form.applyToSubfolders) ? this.form.applyToSubfolders : false,
'permanentlyDelete': (this.form && this.form.permanentlyDelete) ? this.form.permanentlyDelete : false,
'date': this.date,
'folders': folders
}).then(function (data) {
dialogCtrl.loading = true;
Mailbox.selectedFolder.$filter({
"sort": "date",
"asc": false,
"match": "OR"
}).then(function () {
$state.go('mail.account.mailbox', { accountId: vm.accounts[0].id, mailboxId: encodeUriFilter(Mailbox.selectedFolder.path) });
dialogCtrl.loading = false;
$mdDialog.hide();
$mdToast.show(
$mdToast.simple()
.textContent(l('%{0} message(s) deleted', data.nbMessageDeleted))
.position(sgConstant.toastPosition)
.hideDelay(2000));
});
}).catch(function () {
dialogCtrl.loading = false;
$mdDialog.hide();
});
};
},
controllerAs: 'dialogCtrl',
clickOutsideToClose: false,
escapeToClose: false,
});
};
this.delegate = function(account) {
$mdDialog.show({
templateUrl: account.id + '/delegation', // UI/Templates/MailerUI/UIxMailUserDelegation.wox
@@ -271,6 +271,14 @@
});
};
this.cleanMailbox = function () {
// Close sidenav on small devices
if (!$mdMedia(sgConstant['gt-md']))
$mdSidenav('left').close();
$rootScope.$broadcast('showCleanMailboxPanel', {folder: this.folder, account: null}); // Show remove old emails panel (broadcast event to MailboxesController)
};
this.emptyJunkFolder = function() {
return this.emptyFolder(l('Junk folder emptied'));
};
@@ -50,6 +50,13 @@ $sg-login-width: grid-step(5);
margin-bottom: 8px;
}
.create-account-link {
color: rgb(255, 255, 255);
font-size: 1em;
text-decoration: none;
margin-bottom: 5px;
}
.password-lost-link {
color: rgb(255, 255, 255);
font-size: 0.9em;
@@ -452,6 +452,10 @@ md-dialog md-dialog-actions.sg-mail-editor-attachments {
.sogo-raw-html-embed .raw-html-embed__preview-placeholder {
display: none !important;
}
.ck-content p {
margin: revert;
}
}
// Search highlight
@@ -527,4 +531,10 @@ mark {
cursor: pointer;
padding-left: 10px;
padding-right: 10px;
}
/* Clean mailbox */
.clean-mailbox-warn {
color: #f44336;
}