Compare commits

...
18 Commits
Author SHA1 Message Date
smizrahi be3630d009 fix(mail): Keep content of Outlook downlevel-revealed conditional comments. Fixes #6167. 2026-10-02 17:25:02 +02:00
Hivert Quentin 6c93d6b66c fix(mail): fix the sort value 2026-09-21 10:21:26 +02:00
Hivert Quentin aa7f82c09d fix(doc): typos 2026-09-14 17:28:06 +02:00
Hivert Quentin c0a83f5c35 chore(release): 5.12.11 2026-09-14 11:22:21 +02:00
Hivert Quentin 1bf1031ab2 i18n(hu): Update Hungarian translations 2026-09-14 11:12:34 +02:00
Hivert Quentin 012e6eff47 fix(junk): extend list of junk icon available 2026-09-14 10:56:28 +02:00
Hivert Quentin 04a3e98238 fix(pwd): use the proper url for reset password mail part2 2026-09-10 08:11:23 +02:00
Hivert Quentin 3d9853e95b chore(js/css): update generated files 2026-09-10 01:01:19 -04:00
Hivert Quentin 382118a93b fix(pwd): use the proper url for reset password mail 2026-09-07 16:26:09 +02:00
Hivert Quentin 3f4f949664 feat(junk): add junk action on mail view 2026-09-04 18:13:36 +02:00
Hivert Quentin 089b50c0de fix(db): release db channel after using them part 2 2026-09-04 11:30:42 +02:00
Hivert Quentin 152f44b90e fix(db): release db channel after using them 2026-09-03 17:09:44 +02:00
Hivert Quentin d089c4046f fix(UI): use legitimate sorting value 2026-09-03 14:42:51 +02:00
Hivert Quentin 10dc173349 fix(sanitization): update regex for html sanitization 2026-09-03 10:51:45 +02:00
WoodySlum 7ce69e3ea7 Merge pull request #395 from kah-ja/fix/imip-card-template-injection
fix(mail): stop interpreting mail data in compiled part viewers
2026-08-27 11:04:41 +02:00
Jan Kahmen 045a0b9c0a fix(mail): escape mail data placed in attributes of a compiled part
the generic attribute writer used for these two spots does not escape what it
writes, so a value taken from the message ends the attribute and starts a new
one. both are inside a part that is compiled, which is where an injected
handler runs.

* the organizer link took inEvent.organizer.email verbatim. a value such as
  mailto:x@y" onpointerover="... produced a live handler on the anchor, and an
  entity encoded scheme such as javascript: reached the href, where the
  browser decodes it. the href is now built as mailto: plus the parsed address
  and escaped as an attribute value.

* the attachment name paragraph of the image and the link viewer took
  filenameForDisplay verbatim. a quote inside an RFC 2231 encoded filename
  ended the title attribute. the writer escapes & < > there but not the quote,
  so the accessor drops the quote instead of escaping it, which keeps a plain
  filename such as A&B.pdf unchanged in the tooltip.

the img title of the image viewer is left alone: attributes of that element are
escaped by the framework already.
2026-08-17 23:48:41 +02:00
Jan Kahmen 8813677ecb fix(core): keep the @import cleanup working in stringWithoutHTMLInjection
the trailing while loop reuses the regex variable, which by then points at the
angular brace pattern whenever stripAngular is YES. that pattern has two
capture groups while the loop substitutes $1@im****$3, so NSRegularExpression
raises NSInvalidArgumentException and the NS_HANDLER swallows it.

give the @import pattern its own variable and use it in both the replacement
and the loop. the replacement also used the template of the block above, which
dropped the whole style element instead of masking the @import in place, so
test_stringWithoutHTMLInjection failed. it passes again, and a case with
stripAngular YES covers the loop.
2026-08-17 23:03:41 +02:00
Jan Kahmen 0d66d7503d fix(mail): stop interpreting iMIP card text fields as markup
the whole server built html of an iMIP card is rendered through sg-compile
(Message.service.js sets part.compile for UIxMailPartICalViewer), and the user
comment and the description are emitted with escapeHTML="NO". event data from
the invitation is therefore both an angular template and raw html.

47133fdf3 closed the description against interpolation with ng-non-bindable.
this closes both paths for every remaining field:

* ng-non-bindable on the user comment, the location, the organizer common name
  and the raw body shown when the calendar cannot be parsed
* the user comment and the description are read through accessors that escape
  them, so the url detection and insertBR produce the only markup left in the
  output

the marker sits on the leaf containers, not on md-card-content, so the buttons,
the delegation autocomplete and the attendee chips keep being compiled. url
detection still turns a bare url in a comment or a description into a link.
2026-08-17 23:03:41 +02:00
42 changed files with 601 additions and 300 deletions

No files matched your search

+1 -1
View File
@@ -15,9 +15,9 @@
* *
* **************************************************************************/
/* Database configuration (mysql://, postgresql:// or oracle://) */
WOPort = "0.0.0.0:50000";
/* Database configuration (mysql://, postgresql:// or oracle://) */
// MySQL
SOGoProfileURL = "mysql://sogobuild:sogo123@mariadb:3306/sogo/sogo_user_profile";
+27 -1
View File
@@ -2,7 +2,33 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [5.12.100](https://github.com/Alinto/sogo/compare/SOGo-5.12.9...SOGo-5.12.10) (2026-08-13)
## [5.12.11](https://github.com/Alinto/sogo/compare/SOGo-5.12.10...SOGo-5.12.11) (2026-09-14)
### Features
* **junk:** add junk action on mail view ([3f4f949](https://github.com/Alinto/sogo/commit/3f4f9496644953010a4a429f90eae733a50d61c4))
### Bug Fixes
* **core:** keep the [@import](https://github.com/import) cleanup working in stringWithoutHTMLInjection ([8813677](https://github.com/Alinto/sogo/commit/8813677ecb171e5d27cd582989c1d87b308c6df3))
* **db:** release db channel after using them ([152f44b](https://github.com/Alinto/sogo/commit/152f44b90e08013b5c132473a2de249682d997df))
* **db:** release db channel after using them part 2 ([089b50c](https://github.com/Alinto/sogo/commit/089b50c0defdb48e8c0bc0a13334591f3ee2dd11))
* **junk:** extend list of junk icon available ([012e6ef](https://github.com/Alinto/sogo/commit/012e6eff471893efaac033c69ddf7838ca51b791))
* **mail:** escape mail data placed in attributes of a compiled part ([045a0b9](https://github.com/Alinto/sogo/commit/045a0b9c0ac57aeea1b619f281acff0427cd81c7)), closes [#115](https://bugs.sogo.nu/view.php?id=115)
* **mail:** stop interpreting iMIP card text fields as markup ([0d66d75](https://github.com/Alinto/sogo/commit/0d66d7503d8fd147842e87b9b4f1b921986ef44b))
* **pwd:** use the proper url for reset password mail ([382118a](https://github.com/Alinto/sogo/commit/382118a93b6925de2ce7f774abc1865ebea2dbba))
* **pwd:** use the proper url for reset password mail part2 ([04a3e98](https://github.com/Alinto/sogo/commit/04a3e9823889acaf6c247b224f5f7a0108f8f829))
* **sanitization:** update regex for html sanitization ([10dc173](https://github.com/Alinto/sogo/commit/10dc1733496fb2f393537d864d83408e357f2215))
* **UI:** use legitimate sorting value ([d089c40](https://github.com/Alinto/sogo/commit/d089c4046ffac8124874c504491db9d1f15ae650))
### Localization
* **hu:** Update Hungarian translations ([1bf1031](https://github.com/Alinto/sogo/commit/1bf1031ab2932f196f1adcc8fdfc9dea7dfb1f65))
## [5.12.10](https://github.com/Alinto/sogo/compare/SOGo-5.12.9...SOGo-5.12.10) (2026-08-13)
### Features
@@ -840,6 +840,16 @@ Obiously, if your users can connect without specifying a domain, let this parame
|S |SOGoPasswordRecoveryEnabled
|Boolean enable password recovery with secret question or secondary e-mail. Default value is `NO`.
|S |SOGoPasswordRecoveryBaseURLs
| *Since 5.12.11*. List of allowed base URL for password reset link.
`SOGoPasswordRecoveryBaseURLs = ("https://demo.sogo.nu");`
`SOGoPasswordRecoveryBaseURLs = ("https://platform1.sogo.nu", "https://platform2.sogo.nu);`
Do not end the URLs by '/'.
No defaults, will throw an error if empty or unset.
|S |SOGoPasswordRecoveryDomains
|List of domains where password recovery is enabled, for example `(example.org, example.net)`. If empty array `()`, disabled for all domains. If not set, enabled for all domains.
@@ -2886,6 +2896,20 @@ SOGoMailJunkSettings = {
};
----
|D |mailJunkIcon
|Choose the Junk icon. Values are :
https://materialui.co/icon/thumb-down[thumb_down],
https://materialui.co/icon/gpp-bad[gpp_bad],
https://materialui.co/icon/local-fire-department[local_fire_department],
https://materialui.co/icon/bug-report[bug_report],
https://materialui.co/icon/error[error],
https://materialui.co/icon/warning[warning],
https://materialui.co/icon/dangerous[dangerous] and
https://materialui.co/icon/report-gmailerrorred[report_gmailerrorred].
Defaults to `thumb_down`.
|D |SOGoMailKeepDraftsAfterSend
|Parameter used to keep mails in the drafts folder once they have been
sent by SOGo. Defaults to `NO` when unset.
@@ -4284,6 +4308,9 @@ current version of SOGo from the previous release.
[cols="100a"]
|=======================================================================
h|5.12.11
|If you enable Password Recovery, new mandatory settings `SOGoPasswordRecoveryBaseURLs`
h|5.11
|Parameters `SOGoGlobalAddressBookFirstEntries` and `SOGoGlobalAddressBookFirstEntriesCount` has been removed. Please use `listRequiresDot` and `globalAddressBookFirstEntriesCount` instead. Signature are now between a div tag to avoid CKEditor changing the content - set `SOGoForceRawHtmlSignature` to `NO` to leave signature (https://bugs.sogo.nu/view.php?id=5920).
+55 -53
View File
@@ -741,45 +741,43 @@ static BOOL _singleStoreMode = NO;
result = NO;
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
fnames = [self internalNamesFromPath: _path];
if (fnames)
{
sql = [self generateSQLPathFetchForInternalNames: fnames
exactMatch: YES
orDirectSubfolderMatch: NO
withChannel: channel];
if ([sql length])
{
records = [self performSQL: sql withChannel: channel];
if (records)
{
count = [records count];
if (count)
{
fname = [self internalNameFromPath: _path];
if (count == 1)
{
record = [records objectAtIndex: 0];
sname = [record objectForKey: GCSPathRecordName];
result = [fname isEqualToString: sname];
}
else
[self logWithFormat: @"records: %@", records];
}
}
else
[self logWithFormat:@"ERROR(%s): executing SQL failed: '%@'",
__PRETTY_FUNCTION__, sql];
}
else
[self debugWithFormat:@"got no SQL for names: %@", fnames];
{
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
sql = [self generateSQLPathFetchForInternalNames: fnames
exactMatch: YES
orDirectSubfolderMatch: NO
withChannel: channel];
if ([sql length])
{
records = [self performSQL: sql withChannel: channel];
if (records)
{
count = [records count];
if (count)
{
fname = [self internalNameFromPath: _path];
if (count == 1)
{
record = [records objectAtIndex: 0];
sname = [record objectForKey: GCSPathRecordName];
result = [fname isEqualToString: sname];
}
else
[self logWithFormat: @"records: %@", records];
}
}
else
[self logWithFormat:@"ERROR(%s): executing SQL failed: '%@'", __PRETTY_FUNCTION__, sql];
}
else
[self debugWithFormat:@"got no SQL for names: %@", fnames];
}
else
[self debugWithFormat:@"got no internal names for path: '%@'", _path];
@@ -794,21 +792,22 @@ static BOOL _singleStoreMode = NO;
EOAdaptorChannel *channel;
unsigned i, count;
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
if ((fnames = [self internalNamesFromPath:_path]) == nil) {
[self debugWithFormat:@"got no internal names for path: '%@'", _path];
return nil;
}
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
sql = [self generateSQLPathFetchForInternalNames:fnames
exactMatch:NO orDirectSubfolderMatch:(_recursive ? NO : YES) withChannel: channel];
if ([sql length] == 0) {
[self debugWithFormat:@"got no SQL for names: %@", fnames];
[self releaseChannel: channel];
return nil;
}
@@ -859,21 +858,23 @@ static BOOL _singleStoreMode = NO;
unsigned i, count;
EOAdaptorChannel *channel;
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
if ((fnames = [self internalNamesFromPath:_path]) == nil) {
[self debugWithFormat:@"got no internal names for path: '%@'", _path];
return nil;
}
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
sql = [self generateSQLPathAndNameFetchForInternalNames:fnames
exactMatch:NO orDirectSubfolderMatch:(_recursive ? NO : YES) withChannel: channel];
if ([sql length] == 0) {
[self debugWithFormat:@"got no SQL for names: %@", fnames];
[self releaseChannel: channel];
return nil;
}
@@ -883,8 +884,9 @@ static BOOL _singleStoreMode = NO;
return nil;
}
if ((count = [records count]) == 0)
if ((count = [records count]) == 0) {
return emptyArray;
}
result = [NSMutableArray arrayWithCapacity:(count > 128 ? 128 : count)];
@@ -932,18 +934,18 @@ static BOOL _singleStoreMode = NO;
NSDictionary *record;
EOAdaptorChannel *channel;
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
if ((fnames = [self internalNamesFromPath:_path]) == nil) {
[self debugWithFormat:@"got no internal names for path: '%@'", _path];
return nil;
}
/* generate SQL to fetch folder attributes */
if ((channel = [self acquireOpenChannel]) == nil) {
return [NSException exceptionWithName:@"GCSNoChannel"
reason:@"could not "
userInfo:nil];
}
ws = [self generateSQLWhereForInternalNames:fnames
exactMatch:YES orDirectSubfolderMatch:NO withChannel: channel];
+101 -42
View File
@@ -942,12 +942,13 @@ static int cssEscapingCount;
NSScanner *theScanner;
NSError *error;
NSUInteger numberOfMatches;
NSRegularExpression *regex;
NSRegularExpression *regex, *importRegex;
text = nil;
error = nil;
result = [NSString stringWithString: self];
regex = nil;
importRegex = nil;
NS_DURING
{
@@ -986,20 +987,28 @@ static int cssEscapingCount;
// Remove javascript:
regex = [NSRegularExpression regularExpressionWithPattern:@"j[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*a[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*v[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*a[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*c[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*:"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
// loop until stable: a single pass lets nested tokens reconstruct
// the scheme, e.g. "javajavascript:script:" -> "javascript:"
while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) {
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
}
// Remove vbscript:
regex = [NSRegularExpression regularExpressionWithPattern:@"v[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*b[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*c[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*:"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) {
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
}
// Remove livescript:
regex = [NSRegularExpression regularExpressionWithPattern:@"l[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*v[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*c[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*:"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) {
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""];
result = [NSString stringWithString: newResult];
}
// Remove <script
regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*c[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t"
@@ -1031,52 +1040,41 @@ static int cssEscapingCount;
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"</for*"];
result = [NSString stringWithString: newResult];
// Remove onload
regex = [NSRegularExpression regularExpressionWithPattern:@"onload="
// Remove ANY inline event handler (on...=) in one rule instead of an
// incomplete allow list. This also covers obfuscation by whitespace
// before the '=' ("onerror =") and handler names that were not listed
// before (onfocus, onbegin, onanimationstart, ...). With onfocus gone,
// a lone "autofocus" has no handler left to trigger.
regex = [NSRegularExpression regularExpressionWithPattern:@"\\bon(click|error|focus|load|mouseover|animationstart)[\\s\\u200B&#x09;&#x0A;&#x0D;\\r\\n\\t]*="
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onl***="];
result = [NSString stringWithString: newResult];
// Remove onmouseover
regex = [NSRegularExpression regularExpressionWithPattern:@"onmouseover="
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onmouseo***="];
result = [NSString stringWithString: newResult];
// Remove onrepeat
regex = [NSRegularExpression regularExpressionWithPattern:@"onrepeat="
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onrep***="];
result = [NSString stringWithString: newResult];
// Remove onerror
regex = [NSRegularExpression regularExpressionWithPattern:@"onerror="
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onerr***="];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"data-blocked="];
result = [NSString stringWithString: newResult];
// Remove @import css (in style tags)
regex = [NSRegularExpression regularExpressionWithPattern:@"(<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*y[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*l[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e.*)([\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*@[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t)(.*<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*\\/[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*y[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*l[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*>)"
importRegex = [NSRegularExpression regularExpressionWithPattern:@"(<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*y[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*l[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e.*)([\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*@[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*p[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t)(.*<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*\\/[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*s[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*t[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*y[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*l[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*>)"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onrep***="];
newResult = [importRegex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"$1@im****$3"];
result = [NSString stringWithString: newResult];
if(stripAngular) {
// Remove {{ and }} as they are interprated by angularJS with no way of escaping
regex = [NSRegularExpression regularExpressionWithPattern:@"(\\{\\{)|(&#x7b;&#x7b;)"
// Remove {{ and }} as they are interprated by angularJS with no way of escaping.
// Cover the literal form, the hex entity (&#x7b;) AND the decimal entity
// (&#123;), both with optional leading zeros, since the browser decodes
// any of them back to a brace before AngularJS parses the node.
regex = [NSRegularExpression regularExpressionWithPattern:@"(\\{\\{)|(&#x0*7b;&#x0*7b;)|(&#0*123;&#0*123;)"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"{\\\\{"];
result = [NSString stringWithString: newResult];
regex = [NSRegularExpression regularExpressionWithPattern:@"(\\}\\})|(&#x7d;&#x7d;)"
regex = [NSRegularExpression regularExpressionWithPattern:@"(\\}\\})|(&#x0*7d;&#x0*7d;)|(&#0*125;&#0*125;)"
options: NSRegularExpressionCaseInsensitive error:&error];
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"}/}"];
result = [NSString stringWithString: newResult];
}
newResult = result;
while([regex numberOfMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length])] > 0) {
newResult = [regex stringByReplacingMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length]) withTemplate:@"$1@im****$3"];
while([importRegex numberOfMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length])] > 0) {
newResult = [importRegex stringByReplacingMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length]) withTemplate:@"$1@im****$3"];
}
result = [NSString stringWithString: newResult];
}
@@ -1091,14 +1089,75 @@ static int cssEscapingCount;
}
- (NSString *) cleanInvalidHTMLTags {
// Clean HTML invalid tags as reported in https://bugs.sogo.nu/view.php?id=5755
NSString *s;
s = [NSString stringWithString: self];
s = [s stringByReplacingOccurrencesOfString:@"<!-->" withString:@""];
s = [s stringByReplacingOccurrencesOfString:@"<!--<!" withString:@"<!--"];
// Clean HTML invalid tags as reported in https://bugs.sogo.nu/view.php?id=5755 and https://bugs.sogo.nu/view.php?id=6167
// libxml2 (HTML4) sees a standalone empty comment (<!--> or <!--->) as an
// unterminated comment and drops the rest of the document, so remove it.
// Only do it outside of comments: the Outlook "downlevel-revealed" pattern
// <!--[if !mso]><!--> ... <!--<![endif]--> ends its first comment with
// "<!-->", and removing it would hide the content in between.
NSString *result;
unichar *in, *out;
NSUInteger len, i, j, o;
return s;
len = [self length];
if (len == 0)
return [NSString string];
// Work on raw buffers: linear time, bounded memory (no per-comment objects)
in = NSZoneMalloc (NULL, len * sizeof (unichar));
out = NSZoneMalloc (NULL, len * sizeof (unichar));
[self getCharacters: in];
i = o = 0;
while (i < len)
{
if (i + 3 < len
&& in[i] == '<' && in[i+1] == '!' && in[i+2] == '-' && in[i+3] == '-')
{
j = i + 4;
if (j < len && in[j] == '>')
{
// <!-->
i = j + 1;
continue;
}
if (j + 1 < len && in[j] == '-' && in[j+1] == '>')
{
// <!--->
i = j + 2;
continue;
}
// Regular comment: keep it untouched up to its end ("-->" or "--!>",
// as libxml2 accepts both), or up to the end if unterminated
while (j < len)
{
if (j + 2 < len && in[j] == '-' && in[j+1] == '-' && in[j+2] == '>')
{
j += 3;
break;
}
if (j + 3 < len && in[j] == '-' && in[j+1] == '-'
&& in[j+2] == '!' && in[j+3] == '>')
{
j += 4;
break;
}
j++;
}
memcpy (out + o, in + i, (j - i) * sizeof (unichar));
o += j - i;
i = j;
}
else
out[o++] = in[i++];
}
result = [NSString stringWithCharacters: out length: o];
NSZoneFree (NULL, in);
NSZoneFree (NULL, out);
return result;
}
@end
+1
View File
@@ -100,6 +100,7 @@
- (BOOL) notifyOnExternalModifications;
- (NSDictionary *) mailJunkSettings;
- (NSString *) mailJunkIcon;
- (BOOL) createIdentitiesDisabled;
+23
View File
@@ -481,6 +481,29 @@
return [self objectForKey: @"SOGoMailJunkSettings"];
}
- (NSString *) mailJunkIcon
{
NSArray *iconsList;
NSString *icon;
iconsList = [NSArray arrayWithObjects: @"thumb_down",
@"gpp_bad",
@"local_fire_department",
@"bug_report",
@"error",
@"warning",
@"dangerous",
@"report_gmailerrorred",
nil];
icon = [self objectForKey: @"mailJunkIcon"];
if (([icon length] && ![iconsList containsObject:icon]) || ![icon length])
{
icon = @"thumb_down";
}
return icon;
}
- (BOOL) createIdentitiesDisabled
{
return [self boolForKey: @"SOGoCreateIdentitiesDisabled"];
+1
View File
@@ -149,6 +149,7 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
- (BOOL) isEasUIDisabled;
- (BOOL)isPasswordRecoveryEnabled;
- (NSArray *) passwordRecoveryBaseURLs;
- (NSArray *) passwordRecoveryDomains;
- (NSString *) JWTSecret;
+5
View File
@@ -1082,6 +1082,11 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return [self boolForKey: @"SOGoPasswordRecoveryEnabled"];
}
- (NSArray *) passwordRecoveryBaseURLs
{
return [self stringArrayForKey: @"SOGoPasswordRecoveryBaseURLs"];
}
- (NSArray *) passwordRecoveryDomains
{
static NSArray *passwordRecoveryDomains = nil;
+23 -3
View File
@@ -107,15 +107,35 @@
testEquals([[NSString stringWithString:@"<img livescript:test"] stringWithoutHTMLInjection: NO stripAngular: NO], @"<img test");
testEquals([[NSString stringWithString:@"foobar <form action=\"\">bar</form>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <for* action=\"\">bar</for*>");
testEquals([[NSString stringWithString:@"foobar <iframe src=\"\">bar</iframe>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <ifr*** src=\"\">bar</iframe>");
testEquals([[NSString stringWithString:@"foobar <img onload=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img onl***=foo bar");
testEquals([[NSString stringWithString:@"foobar <img onmouseover=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img onmouseo***=foo bar");
testEquals([[NSString stringWithString:@"foobar <img onload=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img data-blocked=foo bar");
testEquals([[NSString stringWithString:@"foobar <img onmouseover=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img data-blocked=foo bar");
// any on...= handler is neutralised, including whitespace before '=' and names
// that were never in the old list
testEquals([[NSString stringWithString:@"<img src=x onerror =alert(1)>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"<img src=x data-blocked=alert(1)>");
testEquals([[NSString stringWithString:@"<input autofocus onfocus=alert(1)>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"<input autofocus data-blocked=alert(1)>");
// deletion filters loop until stable, so nesting cannot rebuild the scheme
testEquals([[NSString stringWithString:@"javajavascript:script:"] stringWithoutHTMLInjection: NO stripAngular: NO], @"");
testEquals([[NSString stringWithString:@"<!DOCTYPE html><html><head><style>@import url(https://foo.bar/malicious.css);.foo{background-color: red; @import url(https://bar.foo/malicious2.css);</style></head><body><table><tr><td>A</td><td>B</td><td>C</td></tr></table></body></html>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"<!DOCTYPE html><html><head><style>@im**** url(https://foo.bar/malicious.css);.foo{background-color: red; @im**** url(https://bar.foo/malicious2.css);</style></head><body><table><tr><td>A</td><td>B</td><td>C</td></tr></table></body></html>");
// the @import cleanup must still run when angular interpolation is stripped as well
testEquals([[NSString stringWithString:@"<style>@import url(https://foo.bar/malicious.css);</style>"] stringWithoutHTMLInjection: NO stripAngular: YES], @"<style>@im**** url(https://foo.bar/malicious.css);</style>");
// literal braces are rewritten so AngularJS cannot interpolate them
testEquals([[NSString stringWithString:@"{{1337*1337}}"] stringWithoutHTMLInjection: NO stripAngular: YES], @"{\\{1337*1337}/}");
// ... and so are the decimal HTML entities the browser would decode back to braces
testEquals([[NSString stringWithString:@"&#123;&#123;1337*1337&#125;&#125;"] stringWithoutHTMLInjection: NO stripAngular: YES], @"{\\{1337*1337}/}");
}
- (void) test_stringCleanInvalidHTMLTags
{
testEquals([[NSString stringWithString:@"<div>Test<!--></div>"] cleanInvalidHTMLTags], @"<div>Test</div>");
testEquals([[NSString stringWithString:@"<div><!--[if !mso]><span>Test</span><!--<![endif]--></div>"] cleanInvalidHTMLTags], @"<div><!--[if !mso]><span>Test</span><!--[endif]--></div>");
testEquals([[NSString stringWithString:@"<div>Test<!---></div>"] cleanInvalidHTMLTags], @"<div>Test</div>");
testEquals([[NSString stringWithString:@"<div>A<!-->B<!-- c -->C<!-->D</div>"] cleanInvalidHTMLTags], @"<div>AB<!-- c -->CD</div>");
testEquals([[NSString stringWithString:@"<div><!--[if !mso]><span>Test</span><!--<![endif]--></div>"] cleanInvalidHTMLTags], @"<div><!--[if !mso]><span>Test</span><!--<![endif]--></div>");
// Outlook "downlevel-revealed" conditional comment: content must stay visible
testEquals([[NSString stringWithString:@"<a><!--[if !mso]><!--> <div><img src=\"x\"/></div> <!--<![endif]--><!--[if mso]><v:fill/><![endif]--></a>"] cleanInvalidHTMLTags], @"<a><!--[if !mso]><!--> <div><img src=\"x\"/></div> <!--<![endif]--><!--[if mso]><v:fill/><![endif]--></a>");
// libxml2 also ends a comment with "--!>"
testEquals([[NSString stringWithString:@"A<!-- x --!>B<!-->C"] cleanInvalidHTMLTags], @"A<!-- x --!>BC");
// unterminated comment is left as is
testEquals([[NSString stringWithString:@"<div>A<!-- B</div>"] cleanInvalidHTMLTags], @"<div>A<!-- B</div>");
}
- (void) test_stringRemoveHTMLTagsExceptAnchorTags
+7 -1
View File
@@ -115,12 +115,18 @@
{
NSMutableDictionary *contactSettings;
NSString *ascending, *sort;
NSArray *sortValues;
SOGoUserSettings *us;
sort = [[self requestData] objectForKey: @"sort"];
ascending = [[self requestData] objectForKey: @"asc"];
if ([sort length])
//Check value of sorting
sortValues = [NSArray arrayWithObjects: @"c_cn", @"c_sn",
@"c_givenname", @"c_mail", @"c_screenname", @"c_o", @"c_telephonenumber", nil];
if ([sort length] && [sortValues containsObject:sort])
{
sort = [self sortKey];
us = [[context activeUser] userSettings];
@@ -44,7 +44,7 @@ reply_info = "Ez egy válasz az ön által kiküldött meghívásra.";
"Save Attachment" = "Melléklet mentése";
"CC" = "Másolat";
"Cancel" = "Mégsem";
"OK" = "OK";
"OK" = "Rendben";
"Comment" = "Megjegyzés:";
"Description" = "Leírás";
"Location" = "Location";
"Location" = "Helyszín";
@@ -46,6 +46,9 @@
- (BOOL) isEndDateOnSameDay;
- (BOOL) hasLocation;
- (NSString *)location;
- (NSString *) organizerHref;
- (NSString *) userComment;
- (NSString *) eventDescription;
@end
@@ -32,6 +32,7 @@
#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSString+misc.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
@@ -417,6 +418,18 @@
return YES;
}
- (NSString *) organizerHref
{
NSString *address;
address = [[[self inEvent] organizer] rfc822Email];
if (![address length])
return nil;
return [[NSString stringWithFormat: @"mailto:%@", address]
stringByEscapingHTMLAttributeValue];
}
- (NSString *) organizerDisplayName
{
iCalPerson *organizer;
@@ -612,4 +625,14 @@
return [[self inEvent] location];
}
- (NSString *) userComment
{
return [[[self inEvent] userComment] stringByEscapingHTMLString];
}
- (NSString *) eventDescription
{
return [[[self authorativeEvent] comment] stringByEscapingHTMLString];
}
@end /* UIxMailPartICalViewer */
+1
View File
@@ -86,6 +86,7 @@
- (NSString *)preferredPathExtension;
- (NSString *)filename;
- (NSString *)filenameForDisplay;
- (NSString *)filenameForTitle;
- (NSFormatter *)sizeFormatter;
/* caches */
+8
View File
@@ -340,6 +340,14 @@
: (id)@"untitled";
}
- (NSString *) filenameForTitle
{
/* the generic attribute writer escapes & but not the quote, so a quote in the
filename would end the title attribute and start a new one */
return [[self filenameForDisplay] stringByReplacingOccurrencesOfString: @"\""
withString: @""];
}
- (NSFormatter *) sizeFormatter
{
return [UIxMailSizeFormatter sharedMailSizeFormatter];
+26 -20
View File
@@ -408,6 +408,7 @@
NSString *sort, *module;
NSMutableDictionary *moduleSettings;
NSDictionary *urlParams, *sortingAttributes;
NSArray *sortValues;
SOGoUser *activeUser;
SOGoUserSettings *us;
BOOL asc, dry;
@@ -424,20 +425,24 @@
us = [activeUser userSettings];
moduleSettings = [us objectForKey: module];
if ([sort length])
{
if ([sort isEqualToString: [self defaultSortKey]] && !asc)
{
if (moduleSettings && !dry)
//Check sort value
sortValues = [NSArray arrayWithObjects: @"SUBJECT", @"FROM",
@"DATE", @"SIZE", @"ARRIVAL", nil];
if ([sort length] && [sortValues containsObject:sort])
{
if ([sort isEqualToString: [self defaultSortKey]] && !asc)
{
if (moduleSettings && !dry)
{
[moduleSettings removeObjectForKey: @"SortingState"];
[us synchronize];
}
}
else if (!dry)
{
// Save the sorting state in the user settings
if (!moduleSettings)
}
else if (!dry)
{
// Save the sorting state in the user settings
if (!moduleSettings)
{
moduleSettings = [NSMutableDictionary dictionary];
[us setObject: moduleSettings forKey: module];
@@ -445,17 +450,18 @@
[moduleSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", (asc ? 1 : 0)], nil]
forKey: @"SortingState"];
[us synchronize];
}
}
}
}
else if (moduleSettings)
{
NSArray *sortState = [moduleSettings objectForKey: @"SortingState"];
if ([sortState count])
{
sort = [[sortState objectAtIndex: 0] uppercaseString];
asc = [[sortState objectAtIndex: 1] boolValue];
}
}
{
NSArray *sortState = [moduleSettings objectForKey: @"SortingState"];
if ([sortState count])
{
sort = [[sortState objectAtIndex: 0] uppercaseString];
asc = [[sortState objectAtIndex: 1] boolValue];
}
}
if (![sort length])
sort = [self defaultSortKey];
+50 -50
View File
@@ -31,53 +31,53 @@
"Download" = "Letöltés";
"Language" = "Nyelv";
"choose" = "Válasszon ...";
"Arabic" = "العربية";
"Basque" = "Euskara";
"Bosnian" = "Bosanski";
"Bulgarian" = "Български";
"Catalan" = "Català";
"ChineseChina" = "简体中文";
"ChineseTaiwan" = "正體中文";
"Croatian" = "Hrvatski";
"Czech" = "Česky";
"Danish" = "Dansk (Danmark)";
"Dutch" = "Nederlands";
"English" = "English";
"Finnish" = "Suomi";
"French" = "Français";
"Galician" = "Galego";
"German" = "Deutsch";
"Greek" = "Ελληνικά";
"Hebrew" = "עברית";
"Arabic" = "Arab";
"Basque" = "Baszk";
"Bosnian" = "Bosnyák";
"Bulgarian" = "Bolgár";
"Catalan" = "Katalán";
"ChineseChina" = "Kínai (egyszerűsített)";
"ChineseTaiwan" = "Kínai (hagyományos)";
"Croatian" = "Horvát";
"Czech" = "Cseh";
"Danish" = "Dán (Dánia)";
"Dutch" = "Holland";
"English" = "Angol";
"Finnish" = "Finn";
"French" = "Francia";
"Galician" = "Galíciai";
"German" = "Német";
"Greek" = "Görög";
"Hebrew" = "Héber";
"Hungarian" = "Magyar";
"Icelandic" = "Íslenska";
"Indonesian" = "bahasa Indonesia";
"Italian" = "Italiano";
"Japanese" = "日本語";
"Korean" = "한국어";
"Kazakh" = "Қазақ";
"Latvian" = "Latviešu";
"Lithuanian" = "Lietuvių";
"Macedonian" = "Македонски";
"Montenegrin" = "Crnogorski";
"NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk";
"Polish" = "Polski";
"Portuguese" = "Português";
"BrazilianPortuguese" = "Português brasileiro";
"Romanian" = "Română";
"Russian" = "Русский";
"Serbian" = "Српски";
"SerbianLatin" = "Srpski";
"Slovak" = "Slovensky";
"Slovenian" = "Slovenščina";
"SpanishSpain" = "Español (España)";
"SpanishArgentina" = "Español (Argentina)";
"Swedish" = "Svenska";
"Thai" = "ภาษา";
"TurkishTurkey" = "Türkçe (Türkiye)";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"Icelandic" = "Izlandi";
"Indonesian" = "Indonéz";
"Italian" = "Olasz";
"Japanese" = "Japán";
"Korean" = "Koreai";
"Kazakh" = "Kazah";
"Latvian" = "Lett";
"Lithuanian" = "Litván";
"Macedonian" = "Macedón";
"Montenegrin" = "Montenegrói";
"NorwegianBokmal" = " Norvég bokmål";
"NorwegianNynorsk" = "Norvég nynorsk";
"Polish" = "Lengyel";
"Portuguese" = "Portugál";
"BrazilianPortuguese" = "Portugál (Brazília)";
"Romanian" = "Román";
"Russian" = "Orosz";
"Serbian" = " Szerb (cirill írással)";
"SerbianLatin" = "Szerb (latin írással)";
"Slovak" = "Szlovák";
"Slovenian" = "Szlovén";
"SpanishSpain" = "Spanyol (Spanyolország)";
"SpanishArgentina" = "Spanyol (Argentína)";
"Swedish" = "Svéd";
"Thai" = "Thai";
"TurkishTurkey" = "Török (Törökország)";
"Ukrainian" = "Ukrán";
"Welsh" = "Walesi";
"About" = "Névjegy";
"AboutBox" = "Az Inverse és az Alinto által fejlesztett SOGo egy teljes funkcionalitású csoportmunka kiszolgáló, melynek fő célkitűzései az egyszerűség és az igény szerinti növekedés (skálázhatóság).<br/><br/>\nA SOGo egy AJAX alapú modern webes felhasználói felületet biztosít, továbbá szabványos protokollok alkalmazásával, mint pl. CalDAV, CardDAV támogatja telepített alkalmazások használatát is. <br/><br/>\nA SOGo a <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> 2. ill. magasabb verziói, továbbá egyes részei a GNU LGPL 2. verziója alatt kerül kiadásra. Ez egy ingyenes szoftver, a módosítása és újra kiadása megengedett.NINCS GARANCIA, a törvény által megengedett mértékben.<br/><br/>\nLátogassa meg <a href=\"http://www.sogo.nu/en/support/community.html\">ezt az oldalt</a> a különböző támogatási lehetőségek megismeréséhez. ";
@@ -87,7 +87,7 @@
"Change your Password" = "Változtassa meg jelszavát";
"The password was changed successfully." = "A jelszó megváltoztatása sikeres.";
"Your password has expired, please enter a new one below" = "A jelszava lejárt, kérem adjon meg egy újat";
"Your password is too weak. Please choose a stronger password to enhance your security" = "Your password is too weak. Please choose a stronger password to enhance your security";
"Your password is too weak. Please choose a stronger password to enhance your security" = "A megadott jelszó túl gyenge. Kérjük, válasszon erősebb jelszót a nagyobb biztonság érdekében";
"Password must not be empty." = "A jelszó nem lehet üres.";
"The passwords do not match. Please try again." = "Jelszavak nem egyeznek meg, kérem próbálja meg újra.";
"Password Grace Period" = "Jelszóváltoztatás türelmi időszak";
@@ -108,11 +108,11 @@
"Unhandled error response" = "Nem kezelt hiba";
"Password change is not supported." = "A jelszó megváltoztatása nem támogatott.";
"Unhandled HTTP error code: %{0}" = "Nem kezelt HTTP hibakód: /{0}";
"Current password" = "Current password";
"Current password" = "Jelenlegi jelszó";
"New password" = "Új jelszó";
"Passwords don't match" = "Passwords don't match";
"Passwords don't match" = "Jelszavak nem egyeznek meg";
"Confirmation" = "Megerősítés";
"Change" = "Change";
"Change" = "Módosítás";
"Cancel" = "Törlés";
"Please wait..." = "Kérem várjon ...";
"Close" = "Bezárás";
+24 -2
View File
@@ -1316,7 +1316,8 @@ static const NSString *kJwtKey = @"jwt";
*/
- (WOResponse *) passwordRecoveryEmailAction
{
NSString *username, *domain, *mode, *uid, *mailDomain, *fromEmail, *toEmail, *jwtToken, *url, *mailContent, *email;
NSString *username, *domain, *mode, *uid, *mailDomain, *fromEmail, *toEmail, *jwtToken, *url, *mailContent, *email, *serverUrl;
NSArray *baseUrls;
NSDictionary *message, *info;
WORequest *request;
SOGoUserManager *um;
@@ -1371,8 +1372,29 @@ static const NSString *kJwtKey = @"jwt";
// Send mail
mailer = [SOGoMailer mailerWithDomainDefaults: dd];
//Get Allowed server URL and check if it's OK
baseUrls = [[SOGoSystemDefaults sharedSystemDefaults] passwordRecoveryBaseURLs];
serverUrl = [[request headers] objectForKey:@"origin"];
if(!(baseUrls && [baseUrls count] > 0))
{
[self logWithFormat: @"Password recovery exception for user %@: empty or unset SOGoPasswordRecoveryBaseURLs", uid];
response = [self responseWithStatus: 403
andString: @"Password recovery email in error"];
return response;
}
if(![baseUrls containsObject:serverUrl])
{
[self logWithFormat: @"Password recovery exception for user %@: invalid request header", uid];
response = [self responseWithStatus: 403
andString: @"Password recovery email in error"];
return response;
}
url = [NSString stringWithFormat:@"%@%@?token=%@"
, [[request headers] objectForKey:@"origin"]
, serverUrl
, [request uri]
, jwtToken];
@@ -152,7 +152,7 @@
"Contacts Names" = "Kapcsolatok nevei";
"Duplicate name" = "Név kettőzése";
"Calendar categories must have unique names." = "Naptár kategóriáknak egyedi névvel kell rendelkezniük.";
"Disable e-mail notifications on CalDAV" = "Disable e-mail notifications on CalDAV";
"Disable e-mail notifications on CalDAV" = "E-mail értesítések kikapcsolása a CalDAV esetén";
/* Default Calendar */
"Default calendar" = "Alapértelmezett naptár";
@@ -205,9 +205,9 @@
"Insert signature on new message" = "Aláírás beszúrása új levél esetén";
"Insert signature on reply" = "Aláírás beszúrása válasz esetén";
"Insert signature on forward" = "Aláírás beszúrása továbbítás esetén";
"Show recipients or sender full email in mailboxes" = "Show recipients or sender full email in mailboxes";
"Hide attachements for inline images" = "Hide attachments for inline images";
"Show attachments above the message" = "Show attachments above the message";
"Show recipients or sender full email in mailboxes" = "A címzettek vagy a feladó teljes e-mail-címének megjelenítése a postafiókokban";
"Hide attachements for inline images" = "Beágyazott képek mellékleteinek elrejtése";
"Show attachments above the message" = "Mellékletek megjelenítése az üzenet felett";
/* Base font size for messages composed in HTML */
"Default font size" = "Alapértelmezett betűméret";
@@ -233,11 +233,11 @@
"Mail Account" = "Levelezési fiók";
"New Mail Account" = "Új email fiók";
"Server Name" = "Kiszolgáló neve";
"Outgoing Server Name (SMTP)" = "Outgoing Server Name (SMTP)";
"Smtp Auth" = "Smtp Auth";
"Outgoing Server Name (SMTP)" = "Levéltovábbító kiszolgáló neve (SMTP)";
"Smtp Auth" = "SMTP hitelesítés";
"Port" = "Port";
"Encryption" = "Titkosítás";
"Outgoing Encryption" = "Outgoing Encryption";
"Outgoing Encryption" = "Kimenő levél titkosítása";
"None" = "Nincs";
"User Name" = "Felhasználónév";
"Full Name" = "Teljes név";
@@ -315,45 +315,45 @@
"Catalan" = "Català";
"ChineseChina" = "简体中文";
"ChineseTaiwan" = "正體中文";
"Croatian" = "Hrvatski";
"Croatian" = "Horvát";
"Czech" = "Česky";
"Danish" = "Dansk (Danmark)";
"Dutch" = "Nederlands";
"English" = "English";
"Finnish" = "Suomi";
"French" = "Français";
"Galician" = "Galego";
"German" = "Deutsch";
"Hebrew" = "עברית";
"Danish" = "Dán (Dánia)";
"Dutch" = "Holland";
"English" = "Angol";
"Finnish" = "Finn";
"French" = "Francia";
"Galician" = "Galíciai";
"German" = "Német";
"Hebrew" = "Héber";
"Hungarian" = "Magyar";
"Icelandic" = "Íslenska";
"Indonesian" = "bahasa Indonesia";
"Italian" = "Italiano";
"Japanese" = "日本語";
"Kazakh" = "Қазақ";
"Korean" = "한국어";
"Latvian" = "Latviešu";
"Lithuanian" = "Lietuvių";
"Macedonian" = "Македонски";
"Montenegrin" = "Crnogorski";
"NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk";
"Polish" = "Polski";
"Portuguese" = "Português";
"BrazilianPortuguese" = "Português brasileiro";
"Romanian" = "Română";
"Russian" = "Русский";
"Serbian" = "Српски";
"SerbianLatin" = "Srpski";
"Slovak" = "Slovensky";
"Slovenian" = "Slovenščina";
"SpanishSpain" = "Español (España)";
"SpanishArgentina" = "Español (Argentina)";
"Swedish" = "Svenska";
"Thai" = "ภาษา";
"TurkishTurkey" = "Türkçe (Türkiye)";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"Icelandic" = "Izlandi";
"Indonesian" = "Indonéz";
"Italian" = "Olasz";
"Japanese" = "Japán";
"Kazakh" = "Kazah";
"Korean" = "Koreai";
"Latvian" = "Lett";
"Lithuanian" = "Litván";
"Macedonian" = "Macedón";
"Montenegrin" = "Montenegrói";
"NorwegianBokmal" = " Norvég bokmål";
"NorwegianNynorsk" = "Norvég nynorsk";
"Polish" = "Lengyel";
"Portuguese" = "Portugál";
"BrazilianPortuguese" = "Portugál (Brazília)";
"Romanian" = "Román";
"Russian" = "Orosz";
"Serbian" = " Szerb (cirill írással)";
"SerbianLatin" = "Szerb (latin írással)";
"Slovak" = "Szlovák";
"Slovenian" = "Szlovén";
"SpanishSpain" = "Spanyol (Spanyolország)";
"SpanishArgentina" = "Spanyol (Argentína)";
"Swedish" = "Svéd";
"Thai" = "Thai";
"TurkishTurkey" = "Török (Törökország)";
"Ukrainian" = "Ukrán";
"Welsh" = "Walesi";
"Refresh View" = "Nézet frissítése";
"refreshview_manually" = "Kézi";
@@ -435,7 +435,7 @@
"Stop processing filter rules" = "Szűrő szabályok feldolgozásának befejezése";
"is under" = "kisebb, mint";
"is over" = "nagyobb, mint";
"is" = "is";
"is" = "-";
"is not" = "nem";
"contains" = "tartalmaz";
"does not contain" = "nem tartalmaz";
@@ -487,8 +487,8 @@
"none" = "Nincs";
"identicon" = "Azonosító ikon";
"monsterid" = "Szörny";
"wavatar" = "Wavatar";
"retro" = "Retro";
"wavatar" = "Wavatár";
"retro" = "Retró";
/* Animation Level */
"Animation Level" = "Animáció szintje";
@@ -511,7 +511,7 @@
"Let SOGo handle everything" = "A SOGo kezeljen mindent";
/* Password Recovery */
"Password recovery mode" = "Password recovery mode";
"Password recovery mode" = "Jelszó helyreállítás módszere";
"Question" = "Kérdés";
"Secondary e-mail" = "Másodlagos email cím";
"Answer" = "Válasz";
+3
View File
@@ -344,6 +344,9 @@ static SoProduct *preferencesProduct = nil;
[[defaults source] setObject: [domainDefaults calendarJitsiRoomPrefix] forKey: @"SOGoCalendarJitsiRoomPrefix"];
}
//Add the Junk Icon pref
[[defaults source] setObject: [domainDefaults mailJunkIcon] forKey: @"mailJunkIcon"];
//
// Default Contacts preferences
//
@@ -65,7 +65,7 @@
"A total of %{0} events were imported in the calendar." = "Összesen %{0} esemény lett importálva a naptárba.";
"Compose E-Mail to All Attendees" = "Üzenet küldése az összes résztvevőnek";
"Compose E-Mail to Undecided Attendees" = "Üzenet küldése az bizonytalan résztvevőnek";
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
"Download iOS - MacOS configuration profile" = "iOS - MacOS konfigurációs profil letöltése";
/* Relative dates */
"Yesterday" = "Tegnap";
@@ -117,7 +117,7 @@
"Save and Close" = "Mentés és bezárás";
"Close" = "Bezárás";
"Invite Attendees" = "Résztvevők meghívása";
"Create Jitsi Meeting" = "Create Jitsi Meeting";
"Create Jitsi Meeting" = "Jitsi megbeszélés létrehozása";
"Attach" = "Csatolás";
"Update" = "Mentés";
"Cancel" = "Mégsem";
@@ -163,7 +163,7 @@
"End" = "Vége";
"Due Date" = "Lejárat";
"Name" = "Név";
"Email" = "Email";
"Email" = "Email cím";
"Status" = "Állapot";
"% complete" = "% kész";
"Location" = "Hely";
@@ -378,7 +378,7 @@
"Show an Alert" = "Riasztás";
"Send an E-mail" = "Email küldése";
"Email Organizer" = "Email szervező";
"Email Attendees (internal users)" = "Email Attendees (internal users)";
"Email Attendees (internal users)" = "Email résztvevők (belső felhasználók)";
"zoom_400" = "400%";
"zoom_200" = "200%";
"zoom_100" = "100%";
@@ -509,7 +509,7 @@ validate_untilbeforeend = "Az ismétlődésnek az első előfordulás után k
"Work days only" = "Csak munkanapok";
"The whole day" = "Az egész nap";
"Between" = "Között";
"and" = "and";
"and" = "és";
"A time conflict exists with one or more attendees.\nWould you like to keep the current settings anyway?"
= "Egy vagy több résztvevő között időütközés van.\nMegtartja ennek ellenére a beállításokat?";
"Would you like to remove them and send the invitation to the remaining attendees?"
@@ -611,7 +611,7 @@ vtodo_class2 = "(Bizalmas feladat)";
"Select ending date" = "Válasszon befejezés dátumot";
"Delegated to" = "Jogok átruházása az alábiaknak";
"Keep sending me updates" = "Továbbiakban küldjön frissítéseket";
"OK" = "OK";
"OK" = "Rendben";
"Confidential" = "Bizalmas";
"Enable" = "Engedélyez";
"Filter" = "Szűrő";
+8 -1
View File
@@ -786,12 +786,19 @@ static NSArray *tasksFields = nil;
- (void) saveSortValue: (NSString *) submodule
{
NSString *sort, *ascending;
NSArray *sortValues;
SOGoUserSettings *us;
NSMutableDictionary *calendarSettings;
sort = [[context request] formValueForKey: @"sort"];
ascending = [[context request] formValueForKey: @"asc"];
if ([sort length])
//Check value of sorting
sortValues = [NSArray arrayWithObjects: @"title", @"location",
@"calendarName", @"start", @"priority", @"category", @"status", @"end", nil];
if ([sort length] && [sortValues containsObject:sort])
{
us = [[context activeUser] userSettings];
calendarSettings = [us objectForKey: @"Calendar"];
+9
View File
@@ -254,6 +254,7 @@
{
WORequest *request;
NSDictionary *params;
NSArray *listValues;
NSString *selectedList;
[self _setupContext];
@@ -261,6 +262,14 @@
params = [[request contentAsString] objectFromJSONString];
selectedList = [params objectForKey: @"list"];
//Check value
listValues = [NSArray arrayWithObjects: @"eventsListView", @"tasksListView", nil];
if([selectedList length] && ![listValues containsObject:selectedList])
{
selectedList = @"eventsListView";
}
[moduleSettings setObject: selectedList
forKey: @"SelectedList"];
[us synchronize];
@@ -17,7 +17,7 @@
</div>
</md-toolbar>
<md-whiteframe class="md-whiteframe-z1" layout="row" layout-align="space-between center">
<pre><var:string value="flatContentAsString" /></pre>
<pre ng-non-bindable=""><var:string value="flatContentAsString" /></pre>
</md-whiteframe>
</div>
</var:if> <!-- if condition="couldParseCalendar" const:negate="1" -->
@@ -137,7 +137,7 @@
<p>
<var:string label:value="Organizer" />
<a var:href="inEvent.organizer.email"
<a ng-non-bindable="" var:href="organizerHref"
><var:string value="organizerDisplayName" /></a>
<var:string label:value="request_info" />
</p>
@@ -147,7 +147,7 @@
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
<p>
<var:string label:value="Organizer" />
<a var:href="inEvent.organizer.email">
<a ng-non-bindable="" var:href="organizerHref">
<var:string value="organizerDisplayName" />
</a>
<var:string label:value="request_info_no_attendee" />
@@ -233,14 +233,14 @@
</var:if>
<!-- the user comment is used in replies -->
<var:if condition="inEvent.userComment.isNotEmpty">
<var:if condition="userComment.isNotEmpty">
<div class="pseudo-input-container">
<label class="pseudo-input-label">
<var:string label:value="Comment"/>
</label>
<div>
<div ng-non-bindable="">
<md-content>
<var:string value="inEvent.userComment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
<var:string value="userComment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
</md-content>
</div>
</div>
@@ -251,7 +251,7 @@
<var:if condition="hasOrganizer" const:value="true">
<div class="pseudo-input-container">
<label class="pseudo-input-label"><var:string label:value="Organizer"/></label>
<div>
<div ng-non-bindable="">
<var:string value="organizerDisplayName"/>
</div>
</div>
@@ -268,7 +268,7 @@
<var:if condition="hasLocation">
<div class="pseudo-input-container">
<label class="pseudo-input-label"><var:string label:value="Location"/></label>
<div>
<div ng-non-bindable="">
<var:string value="location"/>
</div>
</div>
@@ -294,14 +294,14 @@
</div>
</md-list>
<var:if condition="authorativeEvent.comment.isNotEmpty">
<var:if condition="eventDescription.isNotEmpty">
<div class="pseudo-input-container">
<label class="pseudo-input-label">
<var:string label:value="Description"/>
</label>
<div ng-non-bindable="">
<md-content>
<var:string value="authorativeEvent.comment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
<var:string value="eventDescription.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
</md-content>
</div>
</div>
@@ -10,7 +10,7 @@
<img var:src="pathToAttachment"
var:title="filenameForDisplay"><!-- image --></img>
<md-card-content>
<p class="md-caption" var:title="filenameForDisplay">
<p class="md-caption" var:title="filenameForTitle">
<var:string value="filenameForDisplay" />
</p>
</md-card-content>
@@ -6,7 +6,7 @@
xmlns:label="OGo:label">
<md-card>
<md-card-content>
<p class="md-caption sg-attachment-name" var:title="filenameForDisplay">
<p class="md-caption sg-attachment-name" var:title="filenameForTitle">
<var:if condition="preferredPathExtension.length"><span class="sg-label-outline"><var:string value="preferredPathExtension"/></span></var:if>
<var:string value="filenameForDisplay"/>
</p>
@@ -181,7 +181,7 @@
<md-icon>delete</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="mailbox.markOrUnMarkMessagesAsJunk()">
<md-icon ng-hide="::mailbox.service.selectedFolder.type == 'junk'">thumb_down</md-icon>
<md-icon ng-hide="::mailbox.service.selectedFolder.type == 'junk'">{{ mailbox.junkIcon}}</md-icon>
<md-tooltip ng-hide="::mailbox.service.selectedFolder.type == 'junk'" md-direction="bottom"><var:string label:value="Junk"/></md-tooltip>
<md-icon ng-hide="::mailbox.service.selectedFolder.type != 'junk'">thumb_up</md-icon>
<md-tooltip ng-hide="::mailbox.service.selectedFolder.type != 'junk'" md-direction="bottom"><var:string label:value="Not junk"/></md-tooltip>
@@ -45,6 +45,14 @@
<md-icon class="ng-animate-disabled" ng-switch-when="true" rsrc:md-svg-src="img/mark_email_unread.svg"><!-- mark as unread --></md-icon>
<md-icon class="ng-animate-disabled" ng-switch-default="true" rsrc:md-svg-src="img/mark_email_read.svg"><!-- mark as read --></md-icon>
</md-button>
<md-button class="sg-icon-button" label:aria-label="Junk"
ng-hide="::viewer.message.isDraft"
ng-click="viewer.markOrUnMarkAsJunk()">
<md-tooltip md-direction="bottom" ng-hide="::viewer.mailbox.type == 'junk'"><var:string label:value="Junk"/></md-tooltip>
<md-tooltip md-direction="bottom" ng-show="::viewer.mailbox.type == 'junk'"><var:string label:value="Not junk"/></md-tooltip>
<md-icon ng-hide="::viewer.mailbox.type == 'junk'">{{ viewer.junkIcon }}</md-icon>
<md-icon ng-show="::viewer.mailbox.type == 'junk'">thumb_up</md-icon>
</md-button>
<md-button class="sg-icon-button"
ng-hide="::viewer.message.isDraft"
ng-click="viewer.reply($event)"
+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
+1 -1
View File
@@ -1,2 +1,2 @@
!function(){"use strict";function c(e){var t=this;"function"!=typeof e.then&&(angular.extend(this,e),_.forEach(this.identities,function(e){var t;e.fullName&&e.email?e.full=e.fullName+" <"+e.email+">":e.email?e.full="<"+e.email+">":e.full="",e.signature&&(t=angular.element("<div>"+e.signature+"</div>"),e.textSignature=_.map(t.contents(),"textContent").join(" ").trim())}),this.$mailboxes)&&c.$Mailbox.$unwrapCollection(this,c.$q.when({mailboxes:this.$mailboxes})).then(function(e){t.$mailboxes=e})}c.$factory=["$q","$timeout","$log","sgSettings","Resource","Preferences","Mailbox","Message",function(e,t,s,n,i,a,o,r){return angular.extend(c,{$q:e,$timeout:t,$log:s,$$resource:new i(n.activeUser("folderURL")+"Mail",n.activeUser()),$Preferences:a,$Mailbox:o,$Message:r}),c}];try{angular.module("SOGo.MailerUI")}catch(e){angular.module("SOGo.MailerUI",["SOGo.Common"])}angular.module("SOGo.MailerUI").factory("Account",c.$factory),c.$findAll=function(e){return e?c.$unwrapCollection(e):c.$accounts?c.$q.when(c.$accounts):c.$$resource.fetch("","mailAccounts").then(function(e){return c.$unwrapCollection(e)})},c.$unwrapCollection=function(e){var s=[];return angular.forEach(e,function(e,t){e.id=t,s[t]=new c(e)}),c.$accounts=s},c.refreshUnseenCount=function(e){var t,s=1===c.$Preferences.defaults.SOGoMailFetchAllUnseenCountFolders,n=c.$Preferences.defaults.SOGoRefreshViewCheck;if(s)t=[];else{if(!e)throw Error("SOGoMailFetchAllUnseenCountFolders is disabled and no folders list provided");t=e}_.forEach(c.$accounts,function(e){s?_.forEach(e.$$flattenMailboxes,function(e){t.push(e.id)}):(_.includes(t,e.id+"/folderINBOX")||t.push(e.id+"/folderINBOX"),_.forEach(e.$$flattenMailboxes,function(e){angular.isDefined(e.unseenCount)&&!_.includes(t,e.id)&&t.push(e.id)}))}),c.$$resource.post("","unseenCount",{mailboxes:t}).then(function(t){_.forEach(c.$accounts,function(e){_.forEach(e.$$flattenMailboxes,function(e){angular.isDefined(t[e.id])&&(e.unseenCount=t[e.id])})})}),n&&"manually"!=n&&(c.$refreshUnseenCount&&c.$timeout.cancel(c.$refreshUnseenCount),c.$refreshUnseenCount=c.$timeout(angular.bind(this,c.refreshUnseenCount,e),1e3*n.timeInterval()))},c.prototype.getLength=function(){return this.$expanded?this.$flattenMailboxes().length:0},c.prototype.getItemAtIndex=function(e){var t=this.$flattenMailboxes();return 0<=e&&e<t.length?t[e]:null},c.prototype.$getMailboxes=function(e){var a=this,t=e&&e.reload;return this.$mailboxes&&!t?c.$q.when(this.$mailboxes):(!t&&this.$futureMailboxesData||(this.$futureMailboxesData=c.$Mailbox.$find(this,e).then(function(e){function s(e){_.forEach(e,function(e){var t=_.find(n,["id",e.id]);t&&(e.unseenCount=t.unseenCount),e.children&&0<e.children.length&&s(e.children)})}var n=a.$flattenMailboxes({all:!0});a.$mailboxes=e,a.$expanded=!1;s(a.$mailboxes);function t(e){_.forEach(e,function(e){e.$expanded=0<=i.indexOf("/"+e.id),e.children&&0<e.children.length&&t(e.children)})}var i;if(c.$Preferences.settings.Mail.ExpandedFolders){if(angular.isString(c.$Preferences.settings.Mail.ExpandedFolders))try{i=angular.fromJson(c.$Preferences.settings.Mail.ExpandedFolders)}catch(e){c.$log.warn("Can't parse list of expanded folders. String was: "+c.$Preferences.settings.Mail.ExpandedFolders),i=[]}else i=c.$Preferences.settings.Mail.ExpandedFolders;a.$expanded=0<=i.indexOf("/"+a.id),0<i.length&&t(a.$mailboxes)}return c.$accounts&&(a.$expanded|=1==c.$accounts.length),a.$flattenMailboxes({reload:!0}),a.$mailboxes})),this.$futureMailboxesData)},c.prototype.$flattenMailboxes=function(t){function s(e){_.forEach(e,function(e){n.push(e),(t&&t.all||e.$expanded)&&e.children&&0<e.children.length&&s(e.children)})}var n=[],i=[];return!this.$$flattenMailboxes||t&&(t.reload||t.all)?(s(this.$mailboxes),t&&t.all||(this.$$flattenMailboxes=n,t&&t.saveState&&(_.forEach(c.$accounts,function(e){e.$expanded&&i.push("/"+e.id),_.reduce(e.$$flattenMailboxes,function(e,t){return t.$expanded&&e.push("/"+t.id),e},i)}),c.$$resource.post(null,"saveFoldersState",i)))):n=this.$$flattenMailboxes,n},c.prototype.$getMailboxByType=function(s){function n(e){var t=_.find(e,function(e){return e.type==s});return t||angular.forEach(e,function(e){!t&&e.children&&0<e.children.length&&(t=n(e.children))}),t}return n(this.$mailboxes)},c.prototype.$getMailboxByPath=function(s){function n(e){var t=_.find(e,function(e){return e.path==s});return t||angular.forEach(e,function(e){!t&&e.children&&0<e.children.length&&(t=n(e.children))}),t}var e;if(null==(e=n(this.$mailboxes)))throw Error("No mailbox found matching path "+s);return e},c.prototype.$newMailbox=function(e,t){var s=this;return c.$$resource.post(e.toString(),"createFolder",{name:t}).then(function(){s.$getMailboxes({reload:!0})})},c.prototype.getTextSignature=function(e){var t;return e.signature?(t=angular.element("<div>"+e.signature+"</div>"),e.textSignature=_.map(t.contents(),"textContent").join(" ").trim()):e.textSignature="",e.textSignature},c.prototype.$hasCertificate=function(){return this.security&&this.security.hasCLine truncated
!function(){"use strict";function c(e){var t=this;"function"!=typeof e.then&&(angular.extend(this,e),_.forEach(this.identities,function(e){var t;e.fullName&&e.email?e.full=e.fullName+" <"+e.email+">":e.email?e.full="<"+e.email+">":e.full="",e.signature&&(t=angular.element("<div>"+e.signature+"</div>"),e.textSignature=_.map(t.contents(),"textContent").join(" ").trim())}),this.$mailboxes)&&c.$Mailbox.$unwrapCollection(this,c.$q.when({mailboxes:this.$mailboxes})).then(function(e){t.$mailboxes=e})}c.$factory=["$q","$timeout","$log","sgSettings","Resource","Preferences","Mailbox","Message",function(e,t,s,n,i,a,o,r){return angular.extend(c,{$q:e,$timeout:t,$log:s,$$resource:new i(n.activeUser("folderURL")+"Mail",n.activeUser()),$Preferences:a,$Mailbox:o,$Message:r}),c}];try{angular.module("SOGo.MailerUI")}catch(e){angular.module("SOGo.MailerUI",["SOGo.Common"])}angular.module("SOGo.MailerUI").factory("Account",c.$factory),c.$findAll=function(e){return e?c.$unwrapCollection(e):c.$accounts?c.$q.when(c.$accounts):c.$$resource.fetch("","mailAccounts").then(function(e){return c.$unwrapCollection(e)})},c.$unwrapCollection=function(e){var s=[];return angular.forEach(e,function(e,t){e.id=t,s[t]=new c(e)}),c.$accounts=s},c.refreshUnseenCount=function(e){var t,s=1===c.$Preferences.defaults.SOGoMailFetchAllUnseenCountFolders,n=c.$Preferences.defaults.SOGoRefreshViewCheck;if(s)t=[];else{if(!e)throw Error("SOGoMailFetchAllUnseenCountFolders is disabled and no folders list provided");t=e}_.forEach(c.$accounts,function(e){s?_.forEach(e.$$flattenMailboxes,function(e){t.push(e.id)}):(_.includes(t,e.id+"/folderINBOX")||t.push(e.id+"/folderINBOX"),_.forEach(e.$$flattenMailboxes,function(e){angular.isDefined(e.unseenCount)&&!_.includes(t,e.id)&&t.push(e.id)}))}),c.$$resource.post("","unseenCount",{mailboxes:t}).then(function(t){_.forEach(c.$accounts,function(e){_.forEach(e.$$flattenMailboxes,function(e){angular.isDefined(t[e.id])&&(e.unseenCount=t[e.id])})})}),n&&"manually"!=n&&(c.$refreshUnseenCount&&c.$timeout.cancel(c.$refreshUnseenCount),c.$refreshUnseenCount=c.$timeout(angular.bind(this,c.refreshUnseenCount,e),1e3*n.timeInterval()))},c.prototype.getLength=function(){return this.$expanded?this.$flattenMailboxes().length:0},c.prototype.getItemAtIndex=function(e){var t=this.$flattenMailboxes();return 0<=e&&e<t.length?t[e]:null},c.prototype.$getMailboxes=function(e){var a=this,t=e&&e.reload;return this.$mailboxes&&!t?c.$q.when(this.$mailboxes):(!t&&this.$futureMailboxesData||(this.$futureMailboxesData=c.$Mailbox.$find(this,e).then(function(e){function s(e){_.forEach(e,function(e){var t=_.find(n,["id",e.id]);t&&(e.unseenCount=t.unseenCount),e.children&&0<e.children.length&&s(e.children)})}var n=a.$flattenMailboxes({all:!0});a.$mailboxes=e,a.$expanded=!1;s(a.$mailboxes);function t(e){_.forEach(e,function(e){e.$expanded=0<=i.indexOf("/"+e.id),e.children&&0<e.children.length&&t(e.children)})}var i;if(c.$Preferences.settings.Mail.ExpandedFolders){if(angular.isString(c.$Preferences.settings.Mail.ExpandedFolders))try{i=angular.fromJson(c.$Preferences.settings.Mail.ExpandedFolders)}catch(e){c.$log.warn("Can't parse list of expanded folders. String was: "+c.$Preferences.settings.Mail.ExpandedFolders),i=[]}else i=c.$Preferences.settings.Mail.ExpandedFolders;a.$expanded=0<=i.indexOf("/"+a.id),0<i.length&&t(a.$mailboxes)}return c.$accounts&&(a.$expanded|=1==c.$accounts.length),a.$flattenMailboxes({reload:!0}),a.$mailboxes})),this.$futureMailboxesData)},c.prototype.$flattenMailboxes=function(t){function s(e){_.forEach(e,function(e){n.push(e),(t&&t.all||e.$expanded)&&e.children&&0<e.children.length&&s(e.children)})}var n=[],i=[];return!this.$$flattenMailboxes||t&&(t.reload||t.all)?(s(this.$mailboxes),t&&t.all||(this.$$flattenMailboxes=n,t&&t.saveState&&(_.forEach(c.$accounts,function(e){e.$expanded&&i.push("/"+e.id),_.reduce(e.$$flattenMailboxes,function(e,t){return t.$expanded&&e.push("/"+t.id),e},i)}),c.$$resource.post(null,"saveFoldersState",i)))):n=this.$$flattenMailboxes,n},c.prototype.$getMailboxByType=function(s){function n(e){var t=_.find(e,function(e){return e.type==s});return t||angular.forEach(e,function(e){!t&&e.children&&0<e.children.length&&(t=n(e.children))}),t}return n(this.$mailboxes)},c.prototype.$getMailboxByPath=function(s){function n(e){var t=_.find(e,function(e){return e.path==s});return t||angular.forEach(e,function(e){!t&&e.children&&0<e.children.length&&(t=n(e.children))}),t}var e;if(null==(e=n(this.$mailboxes)))throw Error("No mailbox found matching path "+s);return e},c.prototype.$newMailbox=function(e,t){var s=this;return c.$$resource.post(e.toString(),"createFolder",{name:t}).then(function(){s.$getMailboxes({reload:!0})})},c.prototype.getTextSignature=function(e){var t;return e.signature?(t=angular.element("<div>"+e.signature+"</div>"),e.textSignature=_.map(t.contents(),"textContent").join(" ").trim()):e.textSignature="",e.textSignature},c.prototype.$hasCertificate=function(){return this.security&&this.security.hasCLine truncated
//# sourceMappingURL=Mailer.services.js.map
@@ -1 +1 @@
{"version":3,"file":"Mailer.services.js","sources":["Mailer/Account.service.js","Mailer/Mailbox.service.js","Mailer/Message.service.js","Mailer/sgImageGallery.service.js","Mailer/VirtualMailbox.service.js","Mailer/MailboxController.js","Mailer/MailboxesController.js","Mailer/MessageController.js","Mailer/MessageEditorController.js","Mailer/sgAccountSection.directive.js","Mailer/sgIMIP.directive.js","Mailer/sgMailboxListItem.directive.js","Mailer/sgMessageListItem.directive.js","Mailer/sgMessageListItemMain.directive.js","Mailer/sgZoomableImage.directive.js"],"names":["Account","futureAccountData","_this","this","then","angular","extend","_","forEach","identities","identity","element","fullName","email","full","signature","textSignature","map","contents","join","trim","$mailboxes","$Mailbox","$unwrapCollection","$q","when","mailboxes","collection","$factory","$timeout","$log","Settings","Resource","Preferences","Mailbox","Message","$$resource","activeUser","$Preferences","$Message","module","e","factory","$findAll","data","$accounts","fetch","o","i","id","refreshUnseenCount","folders","unseenCountFolders","fetchAllUnseenCountFolders","defaults","SOGoMailFetchAllUnseenCountFolders","refreshViewCheck","SOGoRefreshViewCheck","Error","account","$$flattenMailboxes","mailbox","push","includes","isDefined","unseenCount","post","$refreshUnseenCount","cancel","bind","timeInterval","prototype","getLength","$expanded","$flattenMailboxes","length","getItemAtIndex","index","expandedMailboxes","$getMailboxes","options","reload","$futureMailboxesData","$find","_visitForUnseencount","previousMailbox","find","previousMailboxes","children","all","_visitForExpanded","expandedFolders","indexOf","settings","Mail","ExpandedFolders","isString","fromJson","warn","_visit","allMailboxes","saveState","reduce","$getMailboxByType","type","_find","$getMailboxByPath","path","$newMailbox","name","toString","getTextSignature","$hasCertificate","security","hasCertificate","$certificate","$$certificate","reject","$removeCertificate","updateQuota","percent","description","maxQuota","Math","round","usedSpace","l","formatted","maxMessages","messagesCount","$quota","$newMessage","debug","JSON","stringify","undefined","accountId","mailboxPath","message","$absolutePath","asDraft","accountDefaults","AuxiliaryMailAccounts","alwaysSign","sign","alwaysEncrypt","encrypt","editable","isNew","mailto","isObject","$parseMailto","$addDelegate","user","deferred","defer","param","uid","delegates","resolve","users","status","promise","$removeDelegate","splice","$omit","deep","defaultIdentity","value","key","copy","isReadOnly","pick","isDefault","forceDefaultIdentity","futureMailboxData","$account","init","newMailboxData","create","$unwrap","$rootScope","Acl","PRELOAD","BATCH_DELETE_LIMIT","$$Acl","$query","sort","asc","selectedFolder","$refreshTimeout","$virtualMode","$virtualPath","$searchMode","SortingState","parseInt","constant","LOOKAHEAD","SIZE","createMailboxes","level","isSentFolder","isDraftsFolder","quotas","split","component","asCSSIdentifier","isUndefined","uidsMap","headers","$isLoading","$messages","$visibleMessages","$selectedMessages","$highlightWords","$id","$acl","threaded","$collapsedThreads","threadsCollapsed","$displayName","$isEditable","isEditable","$isSpecial","$icon","$isNoInferiors","isNoInferiors","$shadowData","selectFolder","setSearchMode","searchMode","$lastVisibleIndex","max","$loadMessage","selectedMessages","updateCache","filter","selected","selectedCount","$unselectMessages","isSelectedMessage","messageId","$selectedMessage","selectedMessage","$selectedMessageIndex","hasSelectedMessage","$filter","sortingAttributes","filters","action","labels","searchBy","searchInput","word","cleanedWord","toLowerCase","match","secondFilter","$flaggedOnly","$unseenOnly","$syncToken","syncToken","unseenOnly","flaggedOnly","keys","$filteredLabels","k","f","endIndex","uids","startIndex","loaded","subject","min","loading","futureHeadersData","$unwrapHeaders","flags","isNoSelect","isWritable","getClassName","base","$rename","findParent","parent","parentMailbox","$save","_updateChildren","child","replace","pathRE","oldPath","sibling","localeCompare","RegExp","$compact","$canFolderAs","$setFolderAs","$empty","capitalize","substring","$markAsRead","isread","getLabels","$labels","filteredByLabel","$flagMessages","messages","operation","msgUIDs","forwardMessages","saveSelectedMessages","selectedUIDs","download","exportFolder","filename","open","$delete","$_deleteMessages","firstIndex","forEachRight","selectedIndex","findIndex","updateVisibleMessages","$deleteMessages","batchSize","_deleteMessages","start","end","currentUids","slice","$markOrUnMarkMessagesAsJunk","method","$copyMessages","folder","$moveMessages","$move","parentPath","finally","save","response","error","$reset","Object","assign","childrenArray","collapsedThread","msg","first","collapsed","$broadcast","$futureMailboxData","headersFields","msgObject","hasNewMessages","$topIndex","deleted","jLine truncated
{"version":3,"file":"Mailer.services.js","sources":["Mailer/Account.service.js","Mailer/Mailbox.service.js","Mailer/Message.service.js","Mailer/sgImageGallery.service.js","Mailer/VirtualMailbox.service.js","Mailer/MailboxController.js","Mailer/MailboxesController.js","Mailer/MessageController.js","Mailer/MessageEditorController.js","Mailer/sgAccountSection.directive.js","Mailer/sgIMIP.directive.js","Mailer/sgMailboxListItem.directive.js","Mailer/sgMessageListItem.directive.js","Mailer/sgMessageListItemMain.directive.js","Mailer/sgZoomableImage.directive.js"],"names":["Account","futureAccountData","_this","this","then","angular","extend","_","forEach","identities","identity","element","fullName","email","full","signature","textSignature","map","contents","join","trim","$mailboxes","$Mailbox","$unwrapCollection","$q","when","mailboxes","collection","$factory","$timeout","$log","Settings","Resource","Preferences","Mailbox","Message","$$resource","activeUser","$Preferences","$Message","module","e","factory","$findAll","data","$accounts","fetch","o","i","id","refreshUnseenCount","folders","unseenCountFolders","fetchAllUnseenCountFolders","defaults","SOGoMailFetchAllUnseenCountFolders","refreshViewCheck","SOGoRefreshViewCheck","Error","account","$$flattenMailboxes","mailbox","push","includes","isDefined","unseenCount","post","$refreshUnseenCount","cancel","bind","timeInterval","prototype","getLength","$expanded","$flattenMailboxes","length","getItemAtIndex","index","expandedMailboxes","$getMailboxes","options","reload","$futureMailboxesData","$find","_visitForUnseencount","previousMailbox","find","previousMailboxes","children","all","_visitForExpanded","expandedFolders","indexOf","settings","Mail","ExpandedFolders","isString","fromJson","warn","_visit","allMailboxes","saveState","reduce","$getMailboxByType","type","_find","$getMailboxByPath","path","$newMailbox","name","toString","getTextSignature","$hasCertificate","security","hasCertificate","$certificate","$$certificate","reject","$removeCertificate","updateQuota","percent","description","maxQuota","Math","round","usedSpace","l","formatted","maxMessages","messagesCount","$quota","$newMessage","debug","JSON","stringify","undefined","accountId","mailboxPath","message","$absolutePath","asDraft","accountDefaults","AuxiliaryMailAccounts","alwaysSign","sign","alwaysEncrypt","encrypt","editable","isNew","mailto","isObject","$parseMailto","$addDelegate","user","deferred","defer","param","uid","delegates","resolve","users","status","promise","$removeDelegate","splice","$omit","deep","defaultIdentity","value","key","copy","isReadOnly","pick","isDefault","forceDefaultIdentity","futureMailboxData","$account","init","newMailboxData","create","$unwrap","$rootScope","Acl","PRELOAD","BATCH_DELETE_LIMIT","$$Acl","$query","sort","asc","selectedFolder","$refreshTimeout","$virtualMode","$virtualPath","$searchMode","SortingState","parseInt","constant","LOOKAHEAD","SIZE","createMailboxes","level","isSentFolder","isDraftsFolder","quotas","split","component","asCSSIdentifier","isUndefined","uidsMap","headers","$isLoading","$messages","$visibleMessages","$selectedMessages","$highlightWords","$id","$acl","threaded","$collapsedThreads","threadsCollapsed","$displayName","$isEditable","isEditable","$isSpecial","$icon","mailJunkIcon","$isNoInferiors","isNoInferiors","$shadowData","selectFolder","setSearchMode","searchMode","$lastVisibleIndex","max","$loadMessage","selectedMessages","updateCache","filter","selected","selectedCount","$unselectMessages","isSelectedMessage","messageId","$selectedMessage","selectedMessage","$selectedMessageIndex","hasSelectedMessage","$filter","sortingAttributes","filters","action","labels","searchBy","searchInput","word","cleanedWord","toLowerCase","match","secondFilter","$flaggedOnly","$unseenOnly","$syncToken","syncToken","unseenOnly","flaggedOnly","keys","$filteredLabels","k","f","endIndex","uids","startIndex","loaded","subject","min","loading","futureHeadersData","$unwrapHeaders","flags","isNoSelect","isWritable","getClassName","base","$rename","findParent","parent","parentMailbox","$save","_updateChildren","child","replace","pathRE","oldPath","sibling","localeCompare","RegExp","$compact","$canFolderAs","$setFolderAs","$empty","capitalize","substring","$markAsRead","isread","getLabels","$labels","filteredByLabel","$flagMessages","messages","operation","msgUIDs","forwardMessages","saveSelectedMessages","selectedUIDs","download","exportFolder","filename","open","$delete","$_deleteMessages","firstIndex","forEachRight","selectedIndex","findIndex","updateVisibleMessages","$deleteMessages","batchSize","_deleteMessages","start","end","currentUids","slice","$markOrUnMarkMessagesAsJunk","method","$copyMessages","folder","$moveMessages","$move","parentPath","finally","save","response","error","$reset","Object","assign","childrenArray","collapsedThread","msg","first","collapsed","$broadcast","$futureMailboxData","headersFields","msgObject","hasNewMessages","$topIndeLine truncated
@@ -207,7 +207,7 @@
}
else if (this.type == 'junk') {
this.$displayName = l('JunkFolderName');
this.$icon = 'thumb_down';
this.$icon = Mailbox.$Preferences.defaults.mailJunkIcon;
}
else if (this.type == 'templates') {
this.$displayName = l('TemplatesFolderName');
@@ -36,6 +36,7 @@
this.allSelected = false;
this.isLoadingMessage = false;
this.nextAction = null;
this.junkIcon = Preferences.defaults.mailJunkIcon;
if (!Mailbox.$virtualMode)
this.selectedFolder.getLabels(); // fetch labels from server
@@ -31,6 +31,7 @@
this.$showDetailedRecipients = this.$alwaysShowDetailedRecipients;
this.showRawSource = false;
this.mailInDeletion = -1;
this.junkIcon = Preferences.defaults.mailJunkIcon;
_registerHotkeys(hotkeys);
@@ -319,10 +320,60 @@
}
};
// Select either the next or previous message once the current message
// has been removed from the mailbox (deleted or moved), then close the
// popup if any.
function _selectNextMessage(mailbox, state, index) {
var nextMessage, previousMessage,
nextIndex = index,
$timeout = vm.service.$timeout;
if (angular.isDefined(state)) {
if (index > 0) {
nextIndex -= 1;
nextMessage = mailbox.getItemAtIndex(nextIndex);
}
if (index < mailbox.getLength())
previousMessage = mailbox.getItemAtIndex(index);
if (nextMessage) {
if (nextMessage.isread && previousMessage && !previousMessage.isread) {
nextIndex = index;
nextMessage = previousMessage;
}
}
else if (previousMessage) {
nextIndex = index;
nextMessage = previousMessage;
}
try {
if (nextMessage && $mdMedia(sgConstant['gt-md'])) {
if (Mailbox.$virtualMode)
state.go('mail.account.virtualMailbox.message', {mailboxId: encodeUriFilter(nextMessage.$mailbox.path), messageId: nextMessage.uid});
else
state.go('mail.account.mailbox.message', {messageId: nextMessage.uid});
$timeout(function() {
if (nextIndex < mailbox.$topIndex)
mailbox.$topIndex = nextIndex;
else if (nextIndex > mailbox.$lastVisibleIndex)
mailbox.$topIndex = nextIndex - (mailbox.$lastVisibleIndex - mailbox.$topIndex);
});
}
else {
state.go('mail.account.mailbox').then(function() {
delete mailbox.$selectedMessage;
});
}
}
catch (error) {}
}
vm.closePopup();
}
this.deleteMessage = function() {
var mailbox, message, state, nextMessage, previousMessage,
parentCtrls = $parentControllers(),
$timeout = this.service.$timeout;
var mailbox, message, state,
parentCtrls = $parentControllers();
if (parentCtrls.messageCtrl) {
mailbox = parentCtrls.mailboxCtrl.selectedFolder;
@@ -340,52 +391,9 @@
vm.mailInDeletion = message.uid;
function _success(index) {
var nextIndex = index;
// Remove message object from scope
message = null;
if (angular.isDefined(state)) {
// Select either the next or previous message
if (index > 0) {
nextIndex -= 1;
nextMessage = mailbox.getItemAtIndex(nextIndex);
}
if (index < mailbox.getLength())
previousMessage = mailbox.getItemAtIndex(index);
if (nextMessage) {
if (nextMessage.isread && previousMessage && !previousMessage.isread) {
nextIndex = index;
nextMessage = previousMessage;
}
}
else if (previousMessage) {
nextIndex = index;
nextMessage = previousMessage;
}
try {
if (nextMessage && $mdMedia(sgConstant['gt-md'])) {
if (Mailbox.$virtualMode)
state.go('mail.account.virtualMailbox.message', {mailboxId: encodeUriFilter(nextMessage.$mailbox.path), messageId: nextMessage.uid});
else
state.go('mail.account.mailbox.message', {messageId: nextMessage.uid});
$timeout(function() {
if (nextIndex < mailbox.$topIndex)
mailbox.$topIndex = nextIndex;
else if (nextIndex > mailbox.$lastVisibleIndex)
mailbox.$topIndex = nextIndex - (mailbox.$lastVisibleIndex - mailbox.$topIndex);
});
}
else {
state.go('mail.account.mailbox').then(function() {
message = null;
delete mailbox.$selectedMessage;
});
}
}
catch (error) {}
}
vm.closePopup();
_selectNextMessage(mailbox, state, index);
}
mailbox.$deleteMessages([message]).then(_success, function(response) {
@@ -407,6 +415,39 @@
});
};
this.markOrUnMarkAsJunk = function() {
var mailbox, message, state, account, dstFolder,
parentCtrls = $parentControllers();
if (parentCtrls.messageCtrl) {
mailbox = parentCtrls.mailboxCtrl.selectedFolder;
message = parentCtrls.messageCtrl.message;
state = parentCtrls.messageCtrl.$state;
account = parentCtrls.messageCtrl.account;
}
else {
mailbox = stateMailbox;
message = stateMessage;
state = $state;
account = stateAccount;
}
if (Mailbox.$virtualMode) {
mailbox = Mailbox.selectedFolder; // the VirtualMailbox instance
}
if (mailbox.type == 'junk')
dstFolder = '/' + account.id + '/folderINBOX';
else
dstFolder = '/' + account.$getMailboxByType('junk').id;
mailbox.$markOrUnMarkMessagesAsJunk([message]).then(function() {
mailbox.$moveMessages([message], dstFolder).then(function(index) {
message = null;
_selectNextMessage(mailbox, state, index);
});
});
};
function _showMailEditor($event, message) {
if (_messageDialog() === null) {
var onCompleteDeferred = $q.defer();
@@ -11,10 +11,9 @@ $icon-badge-size: 2 * $baseline-grid;
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url('../fonts/MaterialIcons-Regular.eot'); /* For IE6-8 */
src: local('Material Icons'),
local('MaterialIcons-Regular'),
url('../fonts/MaterialIcons-Regular.woff2') format('woff2'),
/* No local() sources: always use the bundled font so an outdated
Material Icons font installed on the OS can't shadow it. */
src: url('../fonts/MaterialIcons-Regular.woff2') format('woff2'),
url('../fonts/MaterialIcons-Regular.woff') format('woff'),
url('../fonts/MaterialIcons-Regular.ttf') format('truetype');
}
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR_VERSION=5
MINOR_VERSION=12
SUBMINOR_VERSION=10
SUBMINOR_VERSION=11