Compare commits

..
Author SHA1 Message Date
smizrahi 9f96905c3a feat(core): Add URL encryption for GDPR compliancy. Remove log 2024-01-02 13:48:54 +01:00
smizrahi 10d789fb1f feat(core): Add URL encryption for GDPR compliancy 2023-12-22 11:33:40 +01:00
smizrahi d505b874f7 Merge branch 'master' into feature-gdpr 2023-12-20 18:01:40 +01:00
Hivert Quentin cbeaa4cc11 chore(ytnef): missing symbols with centos 2023-12-20 17:02:32 +01:00
Hivert Quentin 427f7f4b4f feature(contact): Show 100 first results for global address book. Fix commit #17eca6f 2023-12-20 15:36:37 +01:00
Hivert Quentin d68bbc836c chore(js/css): update generated files 2023-12-19 01:00:44 -05:00
smizrahi 51b6c0d9a3 fix(ui): Fix text/placeholder overlaps when Chrome autofill applies 2023-12-18 22:42:13 +01:00
Hivert Quentin 5f2e4889f3 chore(js/css): update generated files 2023-12-18 08:27:23 -05:00
smizrahi 37379ba416 fix(preferences): Fix error 500 when changing password 2023-12-18 14:24:50 +01:00
smizrahi 17eca6f96a feature(contact): Show 100 first results for global address book 2023-12-18 08:34:53 +01:00
Hivert Quentin 26c7462eb0 fix(contacts): Custom contacts categories in sogo.conf wasn't working 2023-12-14 18:11:10 +01:00
smizrahi 9ef49bb56f feat(core): Add URL encryption for GDPR compliancy (fix some dav issues) 2023-10-18 16:37:08 +02:00
smizrahi 54a1f922f9 Merge branch 'master' into feature-gdpr 2023-10-18 13:29:29 +02:00
smizrahi 64a6319635 feat(core): Add URL encryption for GDPR compliancy (refactoring) 2023-10-17 16:43:50 +02:00
smizrahi 31c6f78913 feat(core): Add URL encryption for GDPR compliancy 2023-10-17 16:17:25 +02:00
30 changed files with 577 additions and 75 deletions

No files matched your search

@@ -826,7 +826,17 @@ specified as an array of dictionaries.
|D |SOGoCreateIdentitiesDisabled
|Disable identity creation for users in preferences. If `YES`, users won't be able to add new identities and will allow to change only full name, signature and default identity. Default value is `NO`. Note : If this settings is set to `YES`, it will not be possible to crete auxiliary mail accounts.
|S |SOGoURLEncryptionEnabled
|Enable URL encryption to make SOGo GDPR compatible. Setting this parameter to `YES` will encrypt username in URL. The encryption data are cached to avoid high cpu usage, ig the value of thie parameter is changed, memcached server needs to be restarted. If the encryption is enabled, the DAV url will change. Default value is `NO`.
|S |SOGoURLEncryptionPassphrase
|Passphrase for `SOGoURLEncryptionEnabled`. The string must be 128 bits (16 characters). If this settings change, the cache server must be restarted, and the DAV url will change. Default value is `SOGoSuperSecret0`.
|S |SOGoGlobalAddressBookFirstEntries
|Display first entries in Global Address Book. Default value is `NO`. If source is LDAP, the LDAP overlay `sssvlv` must be enabled on the system for server side sorting.
|S |SOGoGlobalAddressBookFirstEntriesCount
|Number of entries displayed when `SOGoGlobalAddressBookFirstEntries` is enabled. Default value is `100`.
|=======================================================================
+11 -4
View File
@@ -349,8 +349,11 @@ static BOOL debugLeaks;
{
if ([[context request] handledByDefaultHandler])
authenticator = [SOGoWebAuthenticator sharedSOGoWebAuthenticator];
else
else {
authenticator = [SOGoDAVAuthenticator sharedSOGoDAVAuthenticator];
[authenticator setContext: context];
}
}
return authenticator;
@@ -363,10 +366,14 @@ static BOOL debugLeaks;
{
SOGoUser *user;
id userFolder;
user = [SOGoUser userWithLogin: _key roles: nil];
NSData *decodedLogin;
NSString *login;
login = [SOGoUser getDecryptedUsernameIfNeeded: _key withContext: _ctx];
user = [SOGoUser userWithLogin: login roles: nil];
if (user)
userFolder = [$(@"SOGoUserFolder") objectWithName: _key
userFolder = [$(@"SOGoUserFolder") objectWithName: login
inContainer: self];
else
userFolder = nil;
@@ -88,7 +88,7 @@
}
tag = [NSArray arrayWithObjects: @"href", XMLNS_WEBDAV, @"D",
[NSString stringWithFormat: @"/SOGo/dav/%@/", nameInContainer],
[NSString stringWithFormat: @"/SOGo/dav/%@/", [self nameInContainer]],
nil];
[addresses addObjectUniquely: tag];
@@ -128,7 +128,7 @@
}
tag = [NSArray arrayWithObjects: @"href", XMLNS_WEBDAV, @"D",
[NSString stringWithFormat: @"/SOGo/dav/%@/", nameInContainer],
[NSString stringWithFormat: @"/SOGo/dav/%@/", [self nameInContainer]],
nil];
[addresses addObjectUniquely: tag];
+31 -14
View File
@@ -434,26 +434,43 @@
{
NSArray *records, *result;
EOSortOrdering *ordering;
BOOL processed;
result = nil;
processed = NO;
if ([filter length] > 0 || ![source listRequiresDot])
[source setListRequiresDot: NO];
if ( ![source listRequiresDot])
{
records = [source fetchContactsMatching: filter
if ([filter length] > 0) {
records = [source fetchContactsMatching: filter
withCriteria: criteria
inDomain: domain];
[childRecords setObjects: records
forKeys: [records objectsForKey: @"c_name"
notFoundMarker: nil]];
records = [self _flattenedRecords: records];
ordering
= [EOSortOrdering sortOrderingWithKey: sortKey
selector: ((sortOrdering == NSOrderedDescending)
? EOCompareCaseInsensitiveDescending
: EOCompareCaseInsensitiveAscending)];
result
= [records sortedArrayUsingKeyOrderArray:
[NSArray arrayWithObject: ordering]];
processed = YES;
} else if ([[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesEnabled]) {
records = [source fetchContactsMatching: filter
withCriteria: criteria
inDomain: domain
limit: [[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesCount]];
processed = YES;
}
if (processed) {
[childRecords setObjects: records
forKeys: [records objectsForKey: @"c_name"
notFoundMarker: nil]];
records = [self _flattenedRecords: records];
ordering
= [EOSortOrdering sortOrderingWithKey: sortKey
selector: ((sortOrdering == NSOrderedDescending)
? EOCompareCaseInsensitiveDescending
: EOCompareCaseInsensitiveAscending)];
result
= [records sortedArrayUsingKeyOrderArray:
[NSArray arrayWithObject: ordering]];
}
}
return result;
+59 -12
View File
@@ -1384,6 +1384,21 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
- (NSArray *) fetchContactsMatching: (NSString *) match
withCriteria: (NSArray *) criteria
inDomain: (NSString *) theDomain
{
if ([match length] > 0) {
return [self fetchContactsMatching: (NSString *) match
withCriteria: (NSArray *) criteria
inDomain: (NSString *) theDomain
limit: -1];
} else {
return [NSMutableArray array];
}
}
- (NSArray *) fetchContactsMatching: (NSString *) match
withCriteria: (NSArray *) criteria
inDomain: (NSString *) theDomain
limit: (int) limit
{
NSAutoreleasePool *pool;
NGLdapConnection *ldapConnection;
@@ -1392,6 +1407,8 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
NSMutableArray *contacts;
EOQualifier *qualifier;
unsigned int i;
NSString *sortAttribute;
BOOL sortReverse;
contacts = [NSMutableArray array];
@@ -1400,18 +1417,48 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
ldapConnection = [self _ldapConnection];
qualifier = [self _qualifierForFilter: match onCriteria: criteria];
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
else /* we do it like before */
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
if (limit > 0) {
[ldapConnection setQuerySizeLimit: limit];
}
if (limit > 0) {
// Sort results
sortAttribute = @"cn";
sortReverse = NO;
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields
sortAttribute: sortAttribute
sortReverse: sortReverse];
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields
sortAttribute: sortAttribute
sortReverse: sortReverse];
else /* we do it like before */
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields
sortAttribute: sortAttribute
sortReverse: sortReverse];
} else {
// No sort results
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
entries = [ldapConnection baseSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
entries = [ldapConnection flatSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
else /* we do it like before */
entries = [ldapConnection deepSearchAtBaseDN: _baseDN
qualifier: qualifier
attributes: _lookupFields];
}
i = 0;
pool = [NSAutoreleasePool new];
+7 -1
View File
@@ -26,6 +26,7 @@
#define NSSTRING_CRYPTO_H
#import <Foundation/NSString.h>
#import <Foundation/Foundation.h>
typedef enum {
encDefault, //!< default encoding, let the algorithm decide
@@ -35,8 +36,10 @@ typedef enum {
} keyEncoding;
@class NSObject;
@class NSScanner;
@interface NSString (SOGoCryptoExtension)
@interface
NSString(SOGoCryptoExtension)
- (BOOL) isEqualToCrypted: (NSString *) cryptedPassword
withDefaultScheme: (NSString *) theScheme
@@ -62,6 +65,9 @@ typedef enum {
+ (NSArray *) getDefaultEncodingForScheme: (NSString *) passwordScheme;
- (NSString *) encodeAES128ECBBase64:(NSString *)passwordScheme encodedURL:(BOOL)encodedURL exception:(NSException **)ex;
- (NSString *) decodeAES128ECBBase64:(NSString *)passwordScheme encodedURL:(BOOL)encodedURL exception:(NSException **)ex;
@end
#endif /* NSSTRING_CRYPTO_H */
+136
View File
@@ -29,6 +29,11 @@
#import "NSData+Crypto.h"
#import <NGExtensions/NGBase64Coding.h>
#import "aes.h"
#define AES_SIZE 8096
#define AES_KEY_SIZE 16
static const NSString *kAES128ECError = @"kAES128ECError";
@implementation NSString (SOGoCryptoExtension)
@@ -349,4 +354,135 @@
return [[NSData encodeDataAsHexString: [d asLM]] uppercaseString];
}
/**
* Encrypts the data using AES 128 ECB mechanism
*
* @param passwordScheme The 128 bits password key
* @param encodedURL YES if the special base64 characters shall be escaped for URL
* @param ex Exception pointer
* @return If successful, encrypted string in base64
*/
- (NSString *) encodeAES128ECBBase64:(NSString *)passwordScheme encodedURL:(BOOL)encodedURL exception:(NSException **)ex
{
NSData *inputData, *keyData, *outputData;
if (AES_KEY_SIZE != [passwordScheme length]) {
*ex = [NSException exceptionWithName:kAES128ECError reason: [NSString stringWithFormat:@"Key must be %d bits", (AES_KEY_SIZE * 8)] userInfo: nil];
return nil;
}
NSString *value;
int size, i;
uint8_t output[AES_SIZE], input[AES_SIZE];
inputData = [self dataUsingEncoding: NSUnicodeStringEncoding];
keyData = [passwordScheme dataUsingEncoding: NSUnicodeStringEncoding];
size = [inputData length] + 16; // Add one unicode char size 16 bits (NUL)
if (inputData == nil) {
*ex = [NSException exceptionWithName:kAES128ECError reason: @"Invalid input data (encrypt)" userInfo: nil];
return nil;
}
if (((AES_SIZE / 2) - 16) < [self length]) {
*ex = [NSException exceptionWithName:kAES128ECError reason: [NSString stringWithFormat:@"Invalid size (encrypt). max size is %d. Current size : %d", ((AES_SIZE / 2) - 16), [self length]] userInfo: nil];
return nil;
}
memset(output, 0x00, AES_SIZE);
memset(input, 0x00, AES_SIZE);
[inputData getBytes: input length: [inputData length]];
input[[inputData length]] = '\0'; // Add NUL
for(i = 0 ; i < (AES_SIZE / 16) ; ++i)
{
AES128_ECB_encrypt(input + (i*16), [keyData bytes], output+(i*16));
}
outputData = [NSData dataWithBytes: (char *)output length: size];
if (outputData) {
value = [outputData base64EncodedStringWithOptions: 0];
if (encodedURL) {
value = [value stringByReplacingOccurrencesOfString: @"+" withString: @"."];
value = [value stringByReplacingOccurrencesOfString: @"/" withString: @"_"];
value = [value stringByReplacingOccurrencesOfString: @"=" withString: @"-"];
}
return value;
} else {
*ex = [NSException exceptionWithName:kAES128ECError reason:@"Empty data" userInfo: nil];
}
return nil;
}
/**
* Decrypts the base64 data using AES 128 ECB mechanism
*
* @param passwordScheme The 128 bits password key
* @param encodedURL YES if the special base64 characters has been escaped for URL
* @param ex Exception pointer
* @return If successful, decrypted string
*/
- (NSString *) decodeAES128ECBBase64:(NSString *)passwordScheme encodedURL:(BOOL)encodedURL exception:(NSException **)ex
{
NSData *inputData, *keyData, *outputData;
NSString *value, *inputString, *tmpStr;
int i;
uint8_t output[AES_SIZE];
if (AES_KEY_SIZE != [passwordScheme length]) {
*ex = [NSException exceptionWithName:kAES128ECError reason: [NSString stringWithFormat:@"Key must be %d bits", (AES_KEY_SIZE * 8)] userInfo: nil];
return nil;
}
value = nil;
keyData = [passwordScheme dataUsingEncoding: NSUnicodeStringEncoding];
memset(output, 0x00, AES_SIZE);
inputString = [NSString stringWithString: self];
if (encodedURL) {
inputString = [inputString stringByReplacingOccurrencesOfString: @"." withString: @"+"];
inputString = [inputString stringByReplacingOccurrencesOfString: @"_" withString: @"/"];
inputString = [inputString stringByReplacingOccurrencesOfString: @"-" withString: @"="];
}
inputData = [[NSData alloc] initWithBase64EncodedString:inputString options:0];
if (inputData == nil) {
*ex = [NSException exceptionWithName:kAES128ECError reason: @"Invalid input data (decrypt)" userInfo: nil];
return nil;
}
if ((AES_SIZE) < [inputData length]) {
*ex = [NSException exceptionWithName:kAES128ECError reason: [NSString stringWithFormat:@"Invalid size (decrypt). max size is %d. Current size : %d", AES_SIZE, [inputData length]] userInfo: nil];
return nil;
}
for(i = 0; i < (AES_SIZE / 16); ++i)
{
AES128_ECB_decrypt([inputData bytes] + (i*16), [keyData bytes], output + (i*16));
}
outputData = [NSData dataWithBytes: output length:([inputData length] - 16)];
if (outputData) {
tmpStr = [[NSString alloc] initWithData: outputData encoding: NSUnicodeStringEncoding];
if (tmpStr) {
value = [NSString stringWithUTF8String: [tmpStr UTF8String]];
} else {
*ex = [NSException exceptionWithName:kAES128ECError reason:@"Empty converted decrypted data" userInfo: nil];
value = nil;
}
[tmpStr release];
} else {
*ex = [NSException exceptionWithName:kAES128ECError reason:@"Empty data" userInfo: nil];
}
return value;
}
@end
+2
View File
@@ -29,6 +29,8 @@
@interface SOGoDAVAuthenticator : SoHTTPAuthenticator <SOGoAuthenticator>
WOContext *context;
+ (id) sharedSOGoDAVAuthenticator;
@end
+12 -1
View File
@@ -41,12 +41,19 @@
{
static SOGoDAVAuthenticator *auth = nil;
if (!auth)
if (!auth) {
auth = [self new];
context = nil;
}
return auth;
}
- (void) setContext: (WOContext *) _context
{
context = _context;
}
- (BOOL) checkLogin: (NSString *) _login
password: (NSString *) _pwd
{
@@ -68,6 +75,10 @@
expire: &expire
grace: &grace]
&& perr == PolicyNoError);
if (context) {
[SOGoUser getEncryptedUsernameIfNeeded: [_login stringByReplacingString: @"%40"
withString: @"@"] withContext: context]; // Create cache entry
}
if (!rc)
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
+1 -1
View File
@@ -533,7 +533,7 @@ static NSArray *childRecordFields = nil;
publicParticle = @"";
path = [NSString stringWithFormat: @"/%@/dav%@/%@/%@/%@/",
appName, publicParticle,
[[self ownerInContext: nil] stringByEscapingURL],
[[SOGoUser getEncryptedUsernameIfNeeded:[self ownerInContext: nil] withContext: context] stringByEscapingURL],
[[container nameInContainer] stringByEscapingURL],
[[self realNameInContainer] stringByEscapingURL]];
currentDavURL = [self davURL];
+2 -2
View File
@@ -365,7 +365,7 @@
NSString *usersUrl;
usersUrl = [NSString stringWithFormat: @"%@%@/",
[[WOApplication application] davURLAsString], owner];
[[WOApplication application] davURLAsString], [SOGoUser getEncryptedUsernameIfNeeded: owner withContext: context]];
ownerHREF = davElementWithContent (@"href", XMLNS_WEBDAV, usersUrl);
return [davElementWithContent (@"owner", XMLNS_WEBDAV, ownerHREF)
@@ -1227,7 +1227,7 @@
davCurrentUserPrincipal = nil;
else
{
s = [NSString stringWithFormat: @"/SOGo/dav/%@", login];
s = [NSString stringWithFormat: @"/SOGo/dav/%@", [SOGoUser getEncryptedUsernameIfNeeded:login withContext:[self context]]];
userHREF = davElementWithContent (@"href", XMLNS_WEBDAV, s);
davCurrentUserPrincipal
= [davElementWithContent (@"current-user-principal",
+4 -2
View File
@@ -32,9 +32,11 @@
acquire: (BOOL) acquire
{
id userFolder;
NSString *login;
if ([key length] > 0 && [SOGoUser userWithLogin: key roles: nil])
userFolder = [SOGoUserFolder objectWithName: key inContainer: self];
login = [SOGoUser getDecryptedUsernameIfNeeded: key withContext: localContext];
if ([key length] > 0 && [SOGoUser userWithLogin: login roles: nil])
userFolder = [SOGoUserFolder objectWithName: login inContainer: self];
else
userFolder = nil;
+5
View File
@@ -75,6 +75,11 @@
- (NSArray *) fetchContactsMatching: (NSString *) filter
withCriteria: (NSArray *) criteria
inDomain: (NSString *) domain;
- (NSArray *)fetchContactsMatching:(NSString *)filter
withCriteria:(NSArray *)criteria
inDomain:(NSString *)domain
limit:(int)limit;
- (NSArray *) lookupContactsWithQualifier: (EOQualifier *) qualifier
andSortOrdering: (EOSortOrdering *) ordering
inDomain: (NSString *) domain;
+6
View File
@@ -133,6 +133,12 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
- (NSArray *) disableSharingAnyAuthUser;
- (NSArray *) disableExport;
- (BOOL) enableGlobalAddressBookFirstEntries;
- (int) globalAddressBookFirstEntriesCount;
- (BOOL)isURLEncryptionEnabled;
- (NSString *)urlEncryptionPassphrase;
@end
#endif /* SOGOSYSTEMDEFAULTS_H */
+33
View File
@@ -819,6 +819,22 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return disableSharing;
}
- (BOOL)isURLEncryptionEnabled {
return [self boolForKey: @"SOGoURLEncryptionEnabled"];
}
- (NSString *) urlEncryptionPassphrase
{
NSString *passphrase;
passphrase = [self stringForKey: @"SOGoURLEncryptionPassphrase"];
if (!passphrase)
passphrase = @"SOGoSuperSecret0"; // Default passphrase
return passphrase;
}
- (NSArray *) disableSharingAnyAuthUser
{
static NSArray *disableSharingAnyAuthUser = nil;
@@ -845,4 +861,21 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return disableExport;
}
- (BOOL) globalAddressBookFirstEntriesEnabled
{
return [self boolForKey: @"SOGoGlobalAddressBookFirstEntries"];
}
- (int) globalAddressBookFirstEntriesCount
{
int v;
v = [self integerForKey: @"SOGoGlobalAddressBookFirstEntriesCount"];
if (!v)
v = 100;
return v;
}
@end
+4
View File
@@ -135,6 +135,10 @@
- (SOGoAppointmentFolder *) personalCalendarFolderInContext: (WOContext *) context;
- (SOGoContactFolder *) personalContactsFolderInContext: (WOContext *) context;
/* Encryption */
+ (NSString *)getEncryptedUsernameIfNeeded:(NSString *)username withContext:(WOContext *)context;
+ (NSString *)getDecryptedUsernameIfNeeded:(NSString *)username withContext:(WOContext *)context;
@end
#endif /* __SOGoUser_H__ */
+83
View File
@@ -39,6 +39,7 @@
#import "SOGoUserManager.h"
#import "SOGoUserSettings.h"
#import "WOResourceManager+SOGo.h"
#import "NSString+Crypto.h"
#if defined(MFA_CONFIG)
#include <liboath/oath.h>
@@ -46,6 +47,8 @@
#import "SOGoUser.h"
static const NSString *kEncryptedUserNamePrefix = @"uenc";
@implementation SoUser (SOGoExtension)
- (SOGoDomainDefaults *) userDefaults
@@ -1197,4 +1200,84 @@
return [accessValue boolValue];
}
/* Encryption */
+ (NSString *) getEncryptedUsernameIfNeeded:(NSString *)username withContext:(WOContext *)context
{
NSException *exception;
NSString *tmp, *cacheKey;
SOGoCache *cache;
WORequest *request;
if (![[SOGoSystemDefaults sharedSystemDefaults] isURLEncryptionEnabled])
return username;
request = [context request];
cache = [SOGoCache sharedCache];
cacheKey = [NSString stringWithFormat: @"%@_%@_%@", kEncryptedUserNamePrefix, username, [request requestHandlerKey]];
exception = nil;
tmp = nil;
tmp = [cache valueForKey: cacheKey];
if (tmp) {
return tmp;
} else {
if (username && [username length] > 0) {
tmp = [username encodeAES128ECBBase64: [[SOGoSystemDefaults sharedSystemDefaults] urlEncryptionPassphrase] encodedURL:YES exception: &exception];
if (!exception) {
[cache setValue:tmp forKey:cacheKey];
return tmp;
} else {
[self errorWithFormat: @"URL Encryption error : %@", [exception reason]];
return username;
}
} else {
[self logWithFormat: @"Empty username for encryption"];
return username;
}
}
}
+ (NSString *) getDecryptedUsernameIfNeeded:(NSString *)username withContext:(WOContext *)context
{
NSException *exception;
NSString *tmp, *cacheKey;
SOGoCache *cache;
WORequest *request;
if (![[SOGoSystemDefaults sharedSystemDefaults] isURLEncryptionEnabled])
return username;
request = [context request];
cache = [SOGoCache sharedCache];
cacheKey = [NSString stringWithFormat: @"%@_%@_%@", kEncryptedUserNamePrefix, username, [request requestHandlerKey]];
exception = nil;
tmp = nil;
tmp = [cache valueForKey: cacheKey];
if (tmp) {
return tmp;
} else {
if (username && [username length] > 0) {
tmp = [username decodeAES128ECBBase64: [[SOGoSystemDefaults sharedSystemDefaults] urlEncryptionPassphrase] encodedURL:YES exception: &exception];
if (tmp) {
[cache setValue:tmp forKey:cacheKey];
} else {
[cache setValue:username forKey:cacheKey];
}
if (!exception) {
return tmp;
} else {
[self errorWithFormat: @"URL Decryption error : %@", [exception reason]];
return username;
}
} else {
[self errorWithFormat: @"Empty username for decryption"];
return username;
}
}
}
@end /* SOGoUser */
+13
View File
@@ -24,6 +24,8 @@
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest+So.h>
#import <SaxObjC/XMLNamespaces.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSString+misc.h>
#import <DOM/DOMNode.h>
@@ -36,6 +38,7 @@
#import "NSArray+Utilities.h"
#import "NSDictionary+Utilities.h"
#import "NSString+Utilities.h"
#import "NSString+Crypto.h"
#import "SOGoUserManager.h"
#import "SOGoPermissions.h"
#import "SOGoSystemDefaults.h"
@@ -83,6 +86,16 @@
return children;
}
- (NSString *) nameInContainer {
return [SOGoUser getEncryptedUsernameIfNeeded: [super nameInContainer] withContext: context];
}
- (NSString *) davURLAsString
{
return [[container davURLAsString]
stringByAppendingFormat: @"%@/", [self nameInContainer]];
}
/* ownership */
- (NSString *) ownerInContext: (WOContext *) _ctx
+18
View File
@@ -924,6 +924,22 @@
- (NSArray *) fetchContactsMatching: (NSString *) filter
withCriteria: (NSArray *) criteria
inDomain: (NSString *) domain
{
if ([filter length] > 0) {
return [self fetchContactsMatching: (NSString *) filter
withCriteria: (NSArray *) criteria
inDomain: (NSString *) domain
limit: -1];
} else {
return [NSMutableArray array];
}
}
- (NSArray *)fetchContactsMatching: (NSString *)filter
withCriteria: (NSArray *)criteria
inDomain: (NSString *)domain
limit: (int)limit
{
EOAdaptorChannel *channel;
NSEnumerator *criteriaList;
@@ -994,6 +1010,8 @@
[sql appendFormat: @" AND %@ IS NULL", _domainField];
}
if (limit > 0)
[sql appendFormat: @" ORDER BY c_cn ASC LIMIT %i", limit];
ex = [channel evaluateExpressionX: sql];
if (!ex)
{
+2
View File
@@ -8,6 +8,8 @@ SOGo_LIBRARIES_DEPEND_UPON += -lcrypto
endif
endif
SOGo_LIBRARIES_DEPEND_UPON += -lytnef
ADDITIONAL_CPPFLAGS += \
-Wall -DCOMPILE_FOR_GSTEP_MAKE=1 \
-DSOGO_MAJOR_VERSION="@\"$(MAJOR_VERSION)\"" \
+2
View File
@@ -343,6 +343,8 @@ static const NSString *kJwtKey = @"jwt";
forKey: @"expire"];
[json setObject: [NSNumber numberWithInt: grace]
forKey: @"grace"];
[json setObject: [SOGoUser getEncryptedUsernameIfNeeded: username withContext: context]
forKey: @"username"];
response = [self responseWithStatus: 200
andJSONRepresentation: json];
+66 -16
View File
@@ -78,6 +78,32 @@ static SoProduct *preferencesProduct = nil;
return labelsDictionary;
}
- (NSDictionary *) _localizedContactsLabels
{
NSArray *categoryLabels, *localizedCategoryLabels;
NSDictionary *labelsDictionary;
labelsDictionary = nil;
localizedCategoryLabels = [[self labelForKey: @"contacts_category_labels"
withResourceManager: [preferencesProduct resourceManager]]
componentsSeparatedByString: @","];
categoryLabels = [[[preferencesProduct resourceManager]
stringForKey: @"contacts_category_labels"
inTableNamed: nil
withDefaultValue: @""
languages: [NSArray arrayWithObject: @"English"]]
componentsSeparatedByString: @","];
if ([localizedCategoryLabels count] == [categoryLabels count])
labelsDictionary = [NSDictionary dictionaryWithObjects: localizedCategoryLabels
forKeys: categoryLabels];
else
[self logWithFormat: @"ERROR: localizable strings contacts_category_labels is incorrect for language %@",
[[[context activeUser] userDefaults] language]];
return labelsDictionary;
}
- (WOResponse *) activeExternalSieveScriptsAction
{
NGSieveClient *client;
@@ -121,7 +147,7 @@ static SoProduct *preferencesProduct = nil;
SOGoUserDefaults *defaults;
SOGoDomainDefaults *domainDefaults;
NSMutableArray *accounts;
NSDictionary *categoryLabels, *vacationOptions;
NSDictionary *calendarCategoryLabels, *contactsCategoriesLabels, *vacationOptions;
if (!preferencesProduct)
{
@@ -131,7 +157,8 @@ static SoProduct *preferencesProduct = nil;
defaults = [[context activeUser] userDefaults];
domainDefaults = [[context activeUser] domainDefaults];
categoryLabels = nil;
calendarCategoryLabels = nil;
contactsCategoriesLabels = nil;
//
// Default General preferences
@@ -223,7 +250,7 @@ static SoProduct *preferencesProduct = nil;
{
NSArray *defaultCalendarCategories;
categoryLabels = [self _localizedCategoryLabels];
calendarCategoryLabels = [self _localizedCategoryLabels];
if ((defaultCalendarCategories = [defaults calendarCategories]))
{
@@ -239,7 +266,7 @@ static SoProduct *preferencesProduct = nil;
for (count = 0; count < max; count++)
{
label = [defaultCalendarCategories objectAtIndex: count];
if (!(localizedLabel = [categoryLabels objectForKey: label]))
if (!(localizedLabel = [calendarCategoryLabels objectForKey: label]))
{
localizedLabel = label;
}
@@ -252,15 +279,15 @@ static SoProduct *preferencesProduct = nil;
{
// Calendar categories are taken from localizable strings
[defaults setCalendarCategories: [categoryLabels allValues]];
[defaults setCalendarCategories: [calendarCategoryLabels allValues]];
}
}
if (![[defaults source] objectForKey: @"SOGoCalendarCategoriesColors"])
{
NSDictionary *defaultCalendarCategoriesColors;
if (!categoryLabels)
categoryLabels = [self _localizedCategoryLabels];
if (!calendarCategoryLabels)
calendarCategoryLabels = [self _localizedCategoryLabels];
if ((defaultCalendarCategoriesColors = [defaults calendarCategoriesColors]))
{
@@ -278,7 +305,7 @@ static SoProduct *preferencesProduct = nil;
for (count = 0; count < max; count++)
{
label = [defaultCalendarCategories objectAtIndex: count];
if (!(localizedLabel = [categoryLabels objectForKey: label]))
if (!(localizedLabel = [calendarCategoryLabels objectForKey: label]))
{
localizedLabel = label;
}
@@ -296,7 +323,7 @@ static SoProduct *preferencesProduct = nil;
NSMutableDictionary *colors;
int i;
calendarCategories = [categoryLabels allValues];
calendarCategories = [calendarCategoryLabels allValues];
colors = [NSMutableDictionary dictionaryWithCapacity: [calendarCategories count]];
for (i = 0; i < [calendarCategories count]; i++)
@@ -311,18 +338,41 @@ static SoProduct *preferencesProduct = nil;
//
// Populate default contact categories, based on the user's preferred language
//
if (![defaults contactsCategories])
if (![[defaults source] objectForKey: @"SOGoContactsCategories"])
{
NSArray *contactsCategories;
contactsCategories = [[[[self labelForKey: @"contacts_category_labels" withResourceManager: [preferencesProduct resourceManager]]
componentsSeparatedByString: @","] trimmedComponents]
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
contactsCategoriesLabels = [self _localizedContactsLabels];
if (!contactsCategories)
contactsCategories = [NSArray array];
if((contactsCategories = [defaults contactsCategories]))
{
// Contact categories are taken from SOGo's configuration or SOGoDefaults.plist
[defaults setContactsCategories: contactsCategories];
NSMutableArray *filteredContactsCategories;
NSString *label, *localizedLabel;
int count, max;
max = [contactsCategories count];
filteredContactsCategories = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
label = [contactsCategories objectAtIndex: count];
if (!(localizedLabel = [contactsCategoriesLabels objectForKey: label]))
{
localizedLabel = label;
}
[filteredContactsCategories addObject: localizedLabel];
}
[defaults setContactsCategories: filteredContactsCategories];
}
else
{
// Contact categories are taken from localizable strings
[defaults setContactsCategories: [contactsCategoriesLabels allValues]];
}
}
if (![[defaults source] objectForKey: @"SOGoMailAddOutgoingAddresses"])
+52 -7
View File
@@ -909,18 +909,63 @@ static NSArray *reminderValues = nil;
//
// Used by templates
//
- (NSDictionary *) _localizedContactsLabels
{
NSArray *categoryLabels, *localizedCategoryLabels;
NSDictionary *labelsDictionary;
labelsDictionary = nil;
localizedCategoryLabels = [[self labelForKey: @"contacts_category_labels"
withResourceManager: [self resourceManager]]
componentsSeparatedByString: @","];
categoryLabels = [[[self resourceManager]
stringForKey: @"contacts_category_labels"
inTableNamed: nil
withDefaultValue: @""
languages: [NSArray arrayWithObject: @"English"]]
componentsSeparatedByString: @","];
if ([localizedCategoryLabels count] == [categoryLabels count])
labelsDictionary = [NSDictionary dictionaryWithObjects: localizedCategoryLabels
forKeys: categoryLabels];
else
[self logWithFormat: @"ERROR: localizable strings contacts_category_labels is incorrect for language %@",
[[[context activeUser] userDefaults] language]];
return labelsDictionary;
}
- (NSString *) defaultContactsCategories
{
NSArray *contactsCategories;
NSArray *labels;
NSDictionary *localizedLabels;
NSMutableArray *defaultCategoriesLabels;
NSString *label, *localizedLabel;
unsigned int i;
contactsCategories = [[[[self labelForKey: @"contacts_category_labels" withResourceManager: [self resourceManager]]
componentsSeparatedByString: @","] trimmedComponents]
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
localizedLabels = [self _localizedContactsLabels];
labels = [[SOGoSystemDefaults sharedSystemDefaults] contactsCategories];
defaultCategoriesLabels = [NSMutableArray array];
if (!contactsCategories)
contactsCategories = [NSArray array];
if(labels)
{
for (i = 0; i < [labels count]; i++)
{
label = [labels objectAtIndex: i];
if (!(localizedLabel = [localizedLabels objectForKey: label]))
{
localizedLabel = label;
}
[defaultCategoriesLabels addObject: localizedLabel];
}
}
else
{
defaultCategoriesLabels = [localizedLabels allValues];
}
return [contactsCategories jsonRepresentation];
return [defaultCategoriesLabels jsonRepresentation];
}
//
@@ -221,7 +221,8 @@
<!-- Remote/domain addressbooks -->
<section>
<md-subheader class="sg-md-subheader--with-secondary-icon"
md-colors="::{background: 'default-background-300'}">
md-colors="::{background: 'default-background-300'}"
ng-if="app.service.$remotes.length > 0">
<var:string label:value="Global Addressbooks"/>
</md-subheader>
<md-list>
+1 -1
View File
@@ -1,2 +1,2 @@
function l(){var n,e,t=arguments[0],o=t,r=arguments;for(labels[t]?o=labels[t]:clabels[t]&&(o=clabels[t]),n=1,e=0;n<r.length;n++,e++)o=o.replace("%{"+e+"}",r[n]);return o=(n=1)<r.length?o.replace(/%((%)|s|d)/g,function(e){var t=null;return e[2]?t=e[2]:(t=r[n],"%d"===e&&(t=parseFloat(t),isNaN(t))&&(t=0),n++),t}):o}function hexToRgb(e){e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}function contrast(e){var t=1,e=hexToRgb(e);if(e){for(var n=[e.r/255,e.g/255,e.b/255],o=0;o<n.length;++o)n[o]=n[o]<=.03928?n[o]/12.92:Math.pow((n[o]+.055)/1.055,2.4);t=.2126*n[0]+.7152*n[1]+.0722*n[2]}return.179<t?"black":"white"}function guid(){function e(){return(65536*(1+Math.random())|0).toString(16).substring(1)}return(e()+e()+"-"+e()+"-4"+e().substr(0,3)+"-"+e()+"-"+e()+e()+e()).toLowerCase()}!function(){"use strict";function e(e,t,n,o,r,i,s){e.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/),r.definePalette("sogo-green",{50:"eaf5e9",100:"cbe5c8",200:"aad6a5",300:"88c781",400:"66b86a",500:"56b04c",600:"4da143",700:"388e3c",800:"367d2e",900:"225e1b",A100:"fafafa",A200:"69f0ae",A400:"00e676",A700:"00c853",contrastDefaultColor:"dark",contrastLightColors:["300","400","500","600","700","800","900"]}),r.definePalette("sogo-blue",{50:"f0faf9",100:"e1f5f3",200:"ceebe8",300:"bfe0dd",400:"b2d6d3",500:"a1ccc8",600:"8ebfbb",700:"7db3b0",800:"639997",900:"4d8080",A100:"d4f7fa",A200:"c3f5fa",A400:"53e3f0",A700:"00b0c0",contrastDefaultColor:"light",contrastDarkColors:["50","100","200"]});e=r.extendPalette("grey",{1e3:"baa870"});r.definePalette("sogo-grey",e),r.theme("default").primaryPalette("sogo-blue",{default:"900","hue-1":"400","hue-2":"800","hue-3":"A700"}).accentPalette("sogo-green",{default:"500","hue-1":"A100","hue-2":"300","hue-3":"A700"}).backgroundPalette("sogo-grey"),r.registerStyles(["md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent,","md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent md-input-container[md-no-float] .md-input {"," background-color: '{{accent-hue-1}}';"," color: '{{foreground-1}}';","}","md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent md-icon {"," color: '{{foreground-1}}';"," fill: '{{foreground-1}}';","}"].join("")),r.registerStyles([".md-autocomplete-suggestions.md-3-line li p {"," color: '{{foreground-2}}';","}"].join("")),r.registerStyles([".sg-time-selection-indicator.sg-time-selected,",".sg-time-selection-indicator:hover.sg-time-selected,",".sg-time-selection-indicator.md-focus.sg-time-selected {"," background: '{{primary-500}}';","}",".sg-timepicker-open .sg-timepicker-icon {"," color: '{{primary-900}}';","}",".sg-timepicker-time,",".sg-timepicker-open .sg-timepicker-input-container {"," background: '{{background-hue-1}}';","}",".sg-timepicker-input-mask-opaque {"," box-shadow: 0 0 0 9999px '{{background-hue-1}}';","}"].join("")),r.registerStyles(["[ui-view=calendars] .hours {"," color: '{{primary-700}}';","}",".attendees .busy {"," background-color: '{{background-1000}}';","}",".attendees .event {"," background-color: '{{primary-300}}';","}"].join("")),r.registerStyles([".sg-message-thread {"," background-color: '{{primary-100}}';","}",".sg-message-thread-first {"," background-color: '{{primary-200}}';","}"].join("")),window.DebugEnabled||(t.debugEnabled(!1),n.debugInfoEnabled(!1),i.disableWarnings(),s.errorOnUnhandledRejections(!1),r.generateThemesOnDemand(!0)),o.interceptors.push("AuthInterceptor"),o.interceptors.push("ErrorInterceptor")}function a(t,e,n,o,r){var i=e.defer(),s=angular.element('<iframe class="ng-hide" src="'+t.UserFolderURL+'recover"></iframe>');return s.on("load",function(){var e=o.get("$state");2<r.config.attempt?(angular.element(t).off("beforeunload"),t.location.href=t.ApplicationBaseURL+e.href(e.current),i.reject()):n(function(){var e=o.get("$http");r.config.attempt?r.config.attempt++:r.config.attempt=1,e(r.config).then(function(e){i.resolve(e)},function(e){i.reject(e)}).finally(function(){n(s.remove,1e3)})},2e3)}),document.body.appendChild(s[0]),i.promise}function t(n,o,r,i){return{response:function(e){var t;return e&&/^application\/json/.test(e.config.headers.Accept)&&/^[\n\r\t ]*<!DOCTYPE html/.test(e.data)?n.usesCASAuthentication||n.usesSAML2Authentication?a(n,o,r,i,e):(t=i.get("$state"),angular.element(n).off("beforeunload"),t.href(t.current)?n.location.href=n.ApplicationBaseURL+t.href(t.current):n.location.href=n.ApplicationBaseURL,o.reject()):e}}}function n(n,o,r,i,s){return{responseError:function(e){var t;if(/^application\/json/.test(e.config.headers.Accept)){if((o.usesCASAuthentication||o.usesSAML2Authentication)&&(-1==e.status||500==e.status&&-1!==document.cookie.indexOf("cas-location")))return a(o,r,i,s,e);o.usesSAML2Authentication&&401==e.status&&!o.recovered?(t=s.get("$state"),angular.element(o).off("beforeunload"),o.recovered=!0,o.location.href=o.ApplicationBaseURL+t.href(t.current)):e.data&&e.data.quiet||n.$broadcast("http:Error",e)}return r.reject(e)}}}angular.Line truncated
function l(){var n,e,t=arguments[0],o=t,r=arguments;for(labels[t]?o=labels[t]:clabels[t]&&(o=clabels[t]),n=1,e=0;n<r.length;n++,e++)o=o.replace("%{"+e+"}",r[n]);return o=(n=1)<r.length?o.replace(/%((%)|s|d)/g,function(e){var t=null;return e[2]?t=e[2]:(t=r[n],"%d"===e&&(t=parseFloat(t),isNaN(t))&&(t=0),n++),t}):o}function hexToRgb(e){e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}function contrast(e){var t=1,e=hexToRgb(e);if(e){for(var n=[e.r/255,e.g/255,e.b/255],o=0;o<n.length;++o)n[o]=n[o]<=.03928?n[o]/12.92:Math.pow((n[o]+.055)/1.055,2.4);t=.2126*n[0]+.7152*n[1]+.0722*n[2]}return.179<t?"black":"white"}function guid(){function e(){return(65536*(1+Math.random())|0).toString(16).substring(1)}return(e()+e()+"-"+e()+"-4"+e().substr(0,3)+"-"+e()+"-"+e()+e()+e()).toLowerCase()}!function(){"use strict";function e(e,t,n,o,r,i,s){e.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/),r.definePalette("sogo-green",{50:"eaf5e9",100:"cbe5c8",200:"aad6a5",300:"88c781",400:"66b86a",500:"56b04c",600:"4da143",700:"388e3c",800:"367d2e",900:"225e1b",A100:"fafafa",A200:"69f0ae",A400:"00e676",A700:"00c853",contrastDefaultColor:"dark",contrastLightColors:["300","400","500","600","700","800","900"]}),r.definePalette("sogo-blue",{50:"f0faf9",100:"e1f5f3",200:"ceebe8",300:"bfe0dd",400:"b2d6d3",500:"a1ccc8",600:"8ebfbb",700:"7db3b0",800:"639997",900:"4d8080",A100:"d4f7fa",A200:"c3f5fa",A400:"53e3f0",A700:"00b0c0",contrastDefaultColor:"light",contrastDarkColors:["50","100","200"]});e=r.extendPalette("grey",{1e3:"baa870"});r.definePalette("sogo-grey",e),r.theme("default").primaryPalette("sogo-blue",{default:"900","hue-1":"400","hue-2":"800","hue-3":"A700"}).accentPalette("sogo-green",{default:"500","hue-1":"A100","hue-2":"300","hue-3":"A700"}).backgroundPalette("sogo-grey"),r.registerStyles(["md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent,","md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent md-input-container[md-no-float] .md-input {"," background-color: '{{accent-hue-1}}';"," color: '{{foreground-1}}';","}","md-toolbar.md-hue-1:not(.md-menu-toolbar).md-accent md-icon {"," color: '{{foreground-1}}';"," fill: '{{foreground-1}}';","}"].join("")),r.registerStyles([".md-autocomplete-suggestions.md-3-line li p {"," color: '{{foreground-2}}';","}"].join("")),r.registerStyles([".sg-time-selection-indicator.sg-time-selected,",".sg-time-selection-indicator:hover.sg-time-selected,",".sg-time-selection-indicator.md-focus.sg-time-selected {"," background: '{{primary-500}}';","}",".sg-timepicker-open .sg-timepicker-icon {"," color: '{{primary-900}}';","}",".sg-timepicker-time,",".sg-timepicker-open .sg-timepicker-input-container {"," background: '{{background-hue-1}}';","}",".sg-timepicker-input-mask-opaque {"," box-shadow: 0 0 0 9999px '{{background-hue-1}}';","}"].join("")),r.registerStyles(["[ui-view=calendars] .hours {"," color: '{{primary-700}}';","}",".attendees .busy {"," background-color: '{{background-1000}}';","}",".attendees .event {"," background-color: '{{primary-300}}';","}"].join("")),r.registerStyles([".sg-message-thread {"," background-color: '{{primary-100}}';","}",".sg-message-thread-first {"," background-color: '{{primary-200}}';","}"].join("")),window.DebugEnabled||(t.debugEnabled(!1),n.debugInfoEnabled(!1),i.disableWarnings(),s.errorOnUnhandledRejections(!1),r.generateThemesOnDemand(!0)),o.interceptors.push("AuthInterceptor"),o.interceptors.push("ErrorInterceptor")}function a(t,e,n,o,r){var i=e.defer(),s=angular.element('<iframe class="ng-hide" src="'+t.UserFolderURL+'recover"></iframe>');return s.on("load",function(){var e=o.get("$state");2<r.config.attempt?(angular.element(t).off("beforeunload"),t.location.href=t.ApplicationBaseURL+e.href(e.current),i.reject()):n(function(){var e=o.get("$http");r.config.attempt?r.config.attempt++:r.config.attempt=1,e(r.config).then(function(e){i.resolve(e)},function(e){i.reject(e)}).finally(function(){n(s.remove,1e3)})},2e3)}),document.body.appendChild(s[0]),i.promise}function t(n,o,r,i){return{response:function(e){var t;return e&&/^application\/json/.test(e.config.headers.Accept)&&/^[\n\r\t ]*<!DOCTYPE html/.test(e.data)?n.usesCASAuthentication||n.usesSAML2Authentication?a(n,o,r,i,e):(t=i.get("$state"),angular.element(n).off("beforeunload"),t.href(t.current)?n.location.href=n.ApplicationBaseURL+t.href(t.current):n.location.href=n.ApplicationBaseURL,o.reject()):e}}}function n(n,o,r,i,s){return{responseError:function(e){var t;if(/^application\/json/.test(e.config.headers.Accept)){if((o.usesCASAuthentication||o.usesSAML2Authentication)&&(-1==e.status||500==e.status&&-1!==document.cookie.indexOf("cas-location")))return a(o,r,i,s,e);o.usesSAML2Authentication&&401==e.status&&!o.recovered?(t=s.get("$state"),angular.element(o).off("beforeunload"),o.recovered=!0,o.location.href=o.ApplicationBaseURL+t.href(t.current)):e.data&&e.data.quiet||n.$broadcast("http:Error",e)}return r.reject(e)}}}angular.Line truncated
//# sourceMappingURL=Common.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Common.js","sources":["Common/utils.js","Common/Common.app.js","Common/mdColors.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/ensureTarget.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/txt2html.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/sgFocus.service.js","Common/sgHotkeys.service.js","Common/sgRippleClick.service.js","Common/User.service.js","Common/sgAutogrow.directive.js","Common/sgAvatarImage.directive.js","Common/sgBlockToggle.directive.js","Common/sgCheckmark.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgDatepickerReadonlyInput.directive.js","Common/sgDraggable.directive.js","Common/sgDroppable.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgLabels.directive.js","Common/sgNoDirtyCheck.directive.js","Common/sgPlaceholder.directive.js","Common/sgQrCode.directive.js","Common/sgResetOnDisabled.directive.js","Common/sgRippleClick.directive.js","Common/sgSearch.directive.js","Common/sgSelectOnly.directive.js","Common/sgSubscribe.directive.js","Common/sgTimepicker.directive.js","Common/sgToggleGrid.directive.js"],"names":["l","i","j","key","arguments","value","args","labels","clabels","length","replace","m","val","parseFloat","isNaN","hexToRgb","hex","result","exec","r","parseInt","g","b","contrast","color","c","Math","pow","guid","S4","random","toString","substring","substr","toLowerCase","configure","$animateProvider","$logProvider","$compileProvider","$httpProvider","$mdThemingProvider","$mdAriaProvider","$qProvider","classNameFilter","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastLightColors","contrastDarkColors","greyMap","extendPalette","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","registerStyles","join","window","DebugEnabled","debugEnabled","debugInfoEnabled","disableWarnings","errorOnUnhandledRejections","generateThemesOnDemand","interceptors","push","renewTicket","$window","$q","$timeout","$injector","response","deferred","defer","iframe","angular","element","UserFolderURL","on","$state","get","config","attempt","off","location","href","ApplicationBaseURL","current","reject","$http","then","resolve","finally","remove","document","body","appendChild","promise","AuthInterceptor","test","headers","Accept","data","usesCASAuthentication","usesSAML2Authentication","ErrorInterceptor","$rootScope","responseError","rejection","status","cookie","indexOf","recovered","quiet","$broadcast","module","isPopup","classList","contains","baseURL","resourcesURL","ResourcesURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","email","UserEmail","language","UserLanguage","folderURL","isSuperUser","IsSuperUser","path","calendar","UserCalendarPath","contacts","UserContactsPath","mail","UserMailPath","preferences","UserPreferencesPath","administration","UserAdministrationPath","help","HelpURL","logoff","UserLogoffPath","minimumSearchLength","isNumber","constant","selection","xs","gt-xs","sm","gt-sm","md","gt-md","lg","gt-lg","xl","print","toastPosition","factory","$inject","_$mdThemingProvider","runBlock","$interpolate","$document","$log","buildCssSelectors","selectors","fgDefault","bgDefault","bdrDefault","fgDefaultHue","bgDefaultHue","fgColor","bgColor","bdrColor","fgHue","bgHue","customSheet","style","head","querySelector","createElement","title","createTextNode","sheet","index","cssRules","deleteRule","addRule","fgInterpolate","bgInterpolate","themeName","paletteName","colorArray","hueName","context","palette","hue","insertRule","addBorderRule","bdrInterpolate","colorValue","forEach","_THEMES","_PALETTES","colors","primary","name","hues","run","decodeUri","decodeURIComponent","filter","encodeUri","encodeURIComponent","ensureTarget","$sce","tree","find","attr","trustAs","html","n","res","txt2html","linkyFilter","text","String","rel","undefined","AclController","$mdDialog","Dialog","usersWithACL","User","folder","vm","this","selectUser","user","$event","target","parentNode","selectedUid","uid","selectedUser","inactive","$rights","users","userToAdd","searchText","folderClassName","isFunction","getClassName","templateName","getElementById","$isAnonymous","userFilter","$query","$filter","$acl","dry","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","alert","confirmChange","confirmation","$confirmRights","showing","message","removeUser","$removeUser","addUser","$addUser","toggleAllRights","$toggleAllRights","hasNoRight","$hasNoRight","showRights","controller","navController","$scope","$interval","$mdSidenav","$mdToast","$mdMedia",Line truncated
{"version":3,"file":"Common.js","sources":["Common/utils.js","Common/Common.app.js","Common/mdColors.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/ensureTarget.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/txt2html.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/sgFocus.service.js","Common/sgHotkeys.service.js","Common/sgRippleClick.service.js","Common/User.service.js","Common/sgAutogrow.directive.js","Common/sgAvatarImage.directive.js","Common/sgBlockToggle.directive.js","Common/sgCheckmark.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgDatepickerReadonlyInput.directive.js","Common/sgDraggable.directive.js","Common/sgDroppable.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgLabels.directive.js","Common/sgNoDirtyCheck.directive.js","Common/sgPlaceholder.directive.js","Common/sgQrCode.directive.js","Common/sgResetOnDisabled.directive.js","Common/sgRippleClick.directive.js","Common/sgSearch.directive.js","Common/sgSelectOnly.directive.js","Common/sgSubscribe.directive.js","Common/sgTimepicker.directive.js","Common/sgToggleGrid.directive.js"],"names":["l","i","j","key","arguments","value","args","labels","clabels","length","replace","m","val","parseFloat","isNaN","hexToRgb","hex","result","exec","r","parseInt","g","b","contrast","color","c","Math","pow","guid","S4","random","toString","substring","substr","toLowerCase","configure","$animateProvider","$logProvider","$compileProvider","$httpProvider","$mdThemingProvider","$mdAriaProvider","$qProvider","classNameFilter","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastLightColors","contrastDarkColors","greyMap","extendPalette","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","registerStyles","join","window","DebugEnabled","debugEnabled","debugInfoEnabled","disableWarnings","errorOnUnhandledRejections","generateThemesOnDemand","interceptors","push","renewTicket","$window","$q","$timeout","$injector","response","deferred","defer","iframe","angular","element","UserFolderURL","on","$state","get","config","attempt","off","location","href","ApplicationBaseURL","current","reject","$http","then","resolve","finally","remove","document","body","appendChild","promise","AuthInterceptor","test","headers","Accept","data","usesCASAuthentication","usesSAML2Authentication","ErrorInterceptor","$rootScope","responseError","rejection","status","cookie","indexOf","recovered","quiet","$broadcast","module","isPopup","classList","contains","baseURL","resourcesURL","ResourcesURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","email","UserEmail","language","UserLanguage","folderURL","isSuperUser","IsSuperUser","path","calendar","UserCalendarPath","contacts","UserContactsPath","mail","UserMailPath","preferences","UserPreferencesPath","administration","UserAdministrationPath","help","HelpURL","logoff","UserLogoffPath","minimumSearchLength","isNumber","constant","selection","xs","gt-xs","sm","gt-sm","md","gt-md","lg","gt-lg","xl","print","toastPosition","factory","$inject","_$mdThemingProvider","runBlock","$interpolate","$document","$log","buildCssSelectors","selectors","fgDefault","bgDefault","bdrDefault","fgDefaultHue","bgDefaultHue","fgColor","bgColor","bdrColor","fgHue","bgHue","customSheet","style","head","querySelector","createElement","title","createTextNode","sheet","index","cssRules","deleteRule","addRule","fgInterpolate","bgInterpolate","themeName","paletteName","colorArray","hueName","context","palette","hue","insertRule","addBorderRule","bdrInterpolate","colorValue","forEach","_THEMES","_PALETTES","colors","primary","name","hues","run","decodeUri","decodeURIComponent","filter","encodeUri","encodeURIComponent","ensureTarget","$sce","tree","find","attr","trustAs","html","n","res","txt2html","linkyFilter","text","String","rel","undefined","AclController","$mdDialog","Dialog","usersWithACL","User","folder","vm","this","selectUser","user","$event","target","parentNode","selectedUid","uid","selectedUser","inactive","$rights","users","userToAdd","searchText","folderClassName","isFunction","getClassName","templateName","getElementById","$isAnonymous","userFilter","$query","$filter","$acl","dry","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","alert","confirmChange","confirmation","$confirmRights","showing","message","removeUser","$removeUser","addUser","$addUser","toggleAllRights","$toggleAllRights","hasNoRight","$hasNoRight","showRights","controller","navController","$scope","$interval","$mdSidenav","$mdToast","$mdMedia",Line truncated
@@ -102,7 +102,7 @@
else if (typeof data.totpDisabled != 'undefined') {
d.resolve({
cn: data.cn,
url: redirectUrl(username, domain),
url: redirectUrl(data.username, domain),
totpdisabled: 1
});
}
@@ -124,12 +124,12 @@
else {
d.resolve({
cn: data.cn,
url: redirectUrl(username, domain)
url: redirectUrl(data.username, domain)
});
}
}
else {
d.resolve({ url: redirectUrl(username, domain) });
d.resolve({ url: redirectUrl(data.username, domain) });
}
}
}, function(error) {
@@ -184,10 +184,6 @@
},
data: { userName: userName, newPassword: newPassword, oldPassword: oldPassword, token: token }
}).then(function() {
// Clean cookies for reauthenticate
$cookies.remove('XSRF-TOKEN', { path: '/SOGo/' });
$cookies.remove('0xHIGHFLYxSOGo', { path: '/SOGo/' });
d.resolve({url: redirectUrl(userName, domain)});
}, function(response) {
var error,
+1 -1
View File
@@ -1,2 +1,2 @@
!function(){"use strict";angular.module("SOGo.MainUI",["SOGo.Common","SOGo.Authentication"]);function e(e,o,s,r,a,n,i,t){var d=this;this.$onInit=function(){this.creds={username:o.cookieUsername,password:null,domain:null,rememberLogin:angular.isDefined(o.cookieUsername)&&0<o.cookieUsername.length},/\blanguage=/.test(o.location.search)&&(this.creds.language=o.language),this.loginState=!1,this.verificationCodePattern="\\d{6}",this.passwords={newPassword:null,newPasswordConfirmation:null,oldPassword:null,visible:!1},this.passwordRecovery={passwordRecoveryEnabled:!1,passwordRecoveryQuestionKey:null,passwordRecoveryQuestion:null,passwordRecoveryMode:null,passwordRecoveryQuestionAnswer:null,passwordRecoveryToken:null,passwordRecoveryLinkTimer:null,passwordRecoverySecondaryEmailText:null,passwordRecoveryMailDomain:null,showLoader:!1},this.showLogin=!1,s(function(){d.showLogin=!0;var e=window.location.search;let o=new URLSearchParams(e).get("token");0<window.location.pathname.indexOf("passwordRecoveryEmail")&&o?3===(e=(o=o.replace(/\//g,"")).split(".")).length&&(d.passwordRecovery.passwordRecoveryToken=o,e=JSON.parse(atob(e[1])),d.creds.username=e.username,d.creds.domain=e.domain,d.passwordRecovery.passwordRecoveryToken=o,d.passwordRecovery.passwordRecoveryMode="SecondaryEmail",d.passwordRecovery.passwordRecoveryEnabled=!0,d.loginState="passwordchange",d.showLogin=!1,t("loginContent")):d.retrievePasswordRecoveryEnabled()},100)},this.login=function(){return d.loginState="authenticating",n.login(d.creds).then(function(e){e.totpmissingkey?(d.loginState="totpcode",i("totpcode")):e.totpdisabled?(d.loginState="totpdisabled",d.cn=e.cn,d.url=e.url):(d.loginState="logged",d.cn=e.cn,d.url=e.url,s(function(){d.continueLogin()},1e3))},function(e){var o,s;d.loginState="error",e.error?d.errorMessage=e.error:0<e.grace?(d.loginState="passwordwillexpire",d.cn=e.cn,d.url=e.url,d.errorMessage=l("You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog.",e.grace)):0<e.expire?(s=86400<e.expire?(o=Math.round(e.expire/86400),l("days")):3600<e.expire?(o=Math.round(e.expire/3600),l("hours")):60<e.expire?(o=Math.round(e.expire/60),l("minutes")):(o=e.expire,l("seconds")),d.loginState="passwordwillexpire",d.cn=e.cn,d.url=e.url,d.errorMessage=l("Your password is going to expire in %{0} %{1}.",o,s)):e.passwordexpired&&(d.loginState="passwordchange",d.url=e.url)}),!1},this.restoreLogin=function(){d.showLogin=!1,"SecretQuestion"===d.passwordRecovery.passwordRecoveryMode?(t("loginContent"),d.passwordRecoveryInfo()):(delete d.creds.verificationCode,d.passwordRecoveryAbort())},this.continueLogin=function(){o.location.href===d.url?o.location.reload(!0):o.location.href=d.url},this.showAbout=function(e){function o(e){this.closeDialog=function(){e.hide()}}a.show({targetEvent:e,templateUrl:"aboutBox.html",controller:o,controllerAs:"about"}),o.$inject=["$mdDialog"]},this.changeLanguage=function(e){o.location.href=ApplicationBaseURL+"login?language="+this.creds.language},this.hello=function(e){return!1},this.canChangePassword=function(e){return this.passwords.newPasswordConfirmation&&this.passwords.newPasswordConfirmation.length&&this.passwords.newPassword!=this.passwords.newPasswordConfirmation?(e.newPasswordConfirmation.$setValidity("newPasswordMismatch",!1),!1):(e.newPasswordConfirmation.$setValidity("newPasswordMismatch",!0),!!(this.passwords.newPassword&&0<this.passwords.newPassword.length&&this.passwords.newPasswordConfirmation&&this.passwords.newPasswordConfirmation.length&&this.passwords.newPassword==this.passwords.newPasswordConfirmation&&(this.isInPasswordRecoveryMode()||!this.loginState&&this.passwords.oldPassword&&0<this.passwords.oldPassword.length||"passwordchange"==this.loginState&&this.passwords.oldPassword&&0<this.passwords.oldPassword.length)))},this.changePassword=function(){n.changePassword(this.creds.username,this.creds.domain,this.passwords.newPassword,this.passwords.oldPassword,this.passwordRecovery.passwordRecoveryToken).then(function(e){d.loginState="message",d.url=e.url,d.errorMessage=l("The password was changed successfully.")},function(e){d.loginState="error",d.errorMessage=e})},this.passwordRecoveryInfo=function(){d.loginState="passwordrecovery",d.passwordRecovery.showLoader=!0,n.passwordRecovery(this.creds.username,this.creds.domain).then(function(e){d.passwordRecovery.passwordRecoveryMode=e.mode,"SecretQuestion"===e.mode?(d.passwordRecovery.passwordRecoveryQuestion=e.secretQuestionLabel,d.passwordRecovery.passwordRecoveryQuestionKey=e.secretQuestion):"SecondaryEmail"===e.mode?d.passwordRecovery.passwordRecoverySecondaryEmailText=l("A link will be sent to %{0}",e.obfuscatedRecoveryEmail):"Disabled"===e.mode&&(d.loginState="error",d.errorMessage=l("No password recovery method has been defined for this user")),d.passwordRecovery.showLoader=!1},function(e){d.loginState="error",d.errorMessage=e,d.passwordRecovery.showLoader=!1})},this.passwordRecoveryEmail=function(){d.passLine truncated
!function(){"use strict";angular.module("SOGo.MainUI",["SOGo.Common","SOGo.Authentication"]);function e(e,o,s,r,a,n,i,t){var d=this;this.$onInit=function(){this.creds={username:o.cookieUsername,password:null,domain:null,rememberLogin:angular.isDefined(o.cookieUsername)&&0<o.cookieUsername.length},/\blanguage=/.test(o.location.search)&&(this.creds.language=o.language),this.loginState=!1,this.verificationCodePattern="\\d{6}",this.passwords={newPassword:null,newPasswordConfirmation:null,oldPassword:null,visible:!1},this.passwordRecovery={passwordRecoveryEnabled:!1,passwordRecoveryQuestionKey:null,passwordRecoveryQuestion:null,passwordRecoveryMode:null,passwordRecoveryQuestionAnswer:null,passwordRecoveryToken:null,passwordRecoveryLinkTimer:null,passwordRecoverySecondaryEmailText:null,passwordRecoveryMailDomain:null,showLoader:!1},this.showLogin=!1,s(function(){d.showLogin=!0;var e=window.location.search;let o=new URLSearchParams(e).get("token");0<window.location.pathname.indexOf("passwordRecoveryEmail")&&o?3===(e=(o=o.replace(/\//g,"")).split(".")).length&&(d.passwordRecovery.passwordRecoveryToken=o,e=JSON.parse(atob(e[1])),d.creds.username=e.username,d.creds.domain=e.domain,d.passwordRecovery.passwordRecoveryToken=o,d.passwordRecovery.passwordRecoveryMode="SecondaryEmail",d.passwordRecovery.passwordRecoveryEnabled=!0,d.loginState="passwordchange",d.showLogin=!1,t("loginContent")):d.retrievePasswordRecoveryEnabled(),0<document.querySelectorAll("*:autofill").length&&document.querySelectorAll("*:autofill").forEach(e=>{e.parentElement.classList.add("md-input-has-value")})},100)},this.login=function(){return d.loginState="authenticating",n.login(d.creds).then(function(e){e.totpmissingkey?(d.loginState="totpcode",i("totpcode")):e.totpdisabled?(d.loginState="totpdisabled",d.cn=e.cn,d.url=e.url):(d.loginState="logged",d.cn=e.cn,d.url=e.url,s(function(){d.continueLogin()},1e3))},function(e){var o,s;d.loginState="error",e.error?d.errorMessage=e.error:0<e.grace?(d.loginState="passwordwillexpire",d.cn=e.cn,d.url=e.url,d.errorMessage=l("You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog.",e.grace)):0<e.expire?(s=86400<e.expire?(o=Math.round(e.expire/86400),l("days")):3600<e.expire?(o=Math.round(e.expire/3600),l("hours")):60<e.expire?(o=Math.round(e.expire/60),l("minutes")):(o=e.expire,l("seconds")),d.loginState="passwordwillexpire",d.cn=e.cn,d.url=e.url,d.errorMessage=l("Your password is going to expire in %{0} %{1}.",o,s)):e.passwordexpired&&(d.loginState="passwordchange",d.url=e.url)}),!1},this.restoreLogin=function(){d.showLogin=!1,"SecretQuestion"===d.passwordRecovery.passwordRecoveryMode?(t("loginContent"),d.passwordRecoveryInfo()):(delete d.creds.verificationCode,d.passwordRecoveryAbort())},this.continueLogin=function(){o.location.href===d.url?o.location.reload(!0):o.location.href=d.url},this.showAbout=function(e){function o(e){this.closeDialog=function(){e.hide()}}a.show({targetEvent:e,templateUrl:"aboutBox.html",controller:o,controllerAs:"about"}),o.$inject=["$mdDialog"]},this.changeLanguage=function(e){o.location.href=ApplicationBaseURL+"login?language="+this.creds.language},this.hello=function(e){return!1},this.canChangePassword=function(e){return this.passwords.newPasswordConfirmation&&this.passwords.newPasswordConfirmation.length&&this.passwords.newPassword!=this.passwords.newPasswordConfirmation?(e.newPasswordConfirmation.$setValidity("newPasswordMismatch",!1),!1):(e.newPasswordConfirmation.$setValidity("newPasswordMismatch",!0),!!(this.passwords.newPassword&&0<this.passwords.newPassword.length&&this.passwords.newPasswordConfirmation&&this.passwords.newPasswordConfirmation.length&&this.passwords.newPassword==this.passwords.newPasswordConfirmation&&(this.isInPasswordRecoveryMode()||!this.loginState&&this.passwords.oldPassword&&0<this.passwords.oldPassword.length||"passwordchange"==this.loginState&&this.passwords.oldPassword&&0<this.passwords.oldPassword.length)))},this.changePassword=function(){n.changePassword(this.creds.username,this.creds.domain,this.passwords.newPassword,this.passwords.oldPassword,this.passwordRecovery.passwordRecoveryToken).then(function(e){d.loginState="message",d.url=e.url,d.errorMessage=l("The password was changed successfully.")},function(e){d.loginState="error",d.errorMessage=e})},this.passwordRecoveryInfo=function(){d.loginState="passwordrecovery",d.passwordRecovery.showLoader=!0,n.passwordRecovery(this.creds.username,this.creds.domain).then(function(e){d.passwordRecovery.passwordRecoveryMode=e.mode,"SecretQuestion"===e.mode?(d.passwordRecovery.passwordRecoveryQuestion=e.secretQuestionLabel,d.passwordRecovery.passwordRecoveryQuestionKey=e.secretQuestion):"SecondaryEmail"===e.mode?d.passwordRecovery.passwordRecoverySecondaryEmailText=l("A link will be sent to %{0}",e.obfuscatedRecoveryEmail):"Disabled"===e.mode&&(d.loginState="error",d.errorMessage=l("No password recovery method has been defined for this user")),d.passwoLine truncated
//# sourceMappingURL=Main.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Main.js","sources":["Main/Main.app.js"],"names":["angular","module","LoginController","$scope","$window","$timeout","Dialog","$mdDialog","Authentication","focus","rippleDo","vm","this","$onInit","creds","username","cookieUsername","password","domain","rememberLogin","isDefined","length","test","location","search","language","loginState","verificationCodePattern","passwords","newPassword","newPasswordConfirmation","oldPassword","visible","passwordRecovery","passwordRecoveryEnabled","passwordRecoveryQuestionKey","passwordRecoveryQuestion","passwordRecoveryMode","passwordRecoveryQuestionAnswer","passwordRecoveryToken","passwordRecoveryLinkTimer","passwordRecoverySecondaryEmailText","passwordRecoveryMailDomain","showLoader","showLogin","queryString","window","let","token","URLSearchParams","get","pathname","indexOf","tokenArray","replace","split","info","JSON","parse","atob","retrievePasswordRecoveryEnabled","login","then","data","totpmissingkey","totpdisabled","cn","url","continueLogin","msg","value","string","error","errorMessage","grace","l","expire","Math","round","passwordexpired","restoreLogin","passwordRecoveryInfo","verificationCode","passwordRecoveryAbort","href","reload","showAbout","$event","AboutDialogController","closeDialog","hide","show","targetEvent","templateUrl","controller","controllerAs","$inject","changeLanguage","ApplicationBaseURL","hello","form","canChangePassword","$setValidity","isInPasswordRecoveryMode","changePassword","mode","secretQuestionLabel","secretQuestion","obfuscatedRecoveryEmail","passwordRecoveryEmail","passwordRecoveryCheck","usernameChanged","clearTimeout","setTimeout","mailDomain","changePasswordVisibility","field","document","getElementById","type","innerHTML"],"mappings":"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 truncated
{"version":3,"file":"Main.js","sources":["Main/Main.app.js"],"names":["angular","module","LoginController","$scope","$window","$timeout","Dialog","$mdDialog","Authentication","focus","rippleDo","vm","this","$onInit","creds","username","cookieUsername","password","domain","rememberLogin","isDefined","length","test","location","search","language","loginState","verificationCodePattern","passwords","newPassword","newPasswordConfirmation","oldPassword","visible","passwordRecovery","passwordRecoveryEnabled","passwordRecoveryQuestionKey","passwordRecoveryQuestion","passwordRecoveryMode","passwordRecoveryQuestionAnswer","passwordRecoveryToken","passwordRecoveryLinkTimer","passwordRecoverySecondaryEmailText","passwordRecoveryMailDomain","showLoader","showLogin","queryString","window","let","token","URLSearchParams","get","pathname","indexOf","tokenArray","replace","split","info","JSON","parse","atob","retrievePasswordRecoveryEnabled","document","querySelectorAll","forEach","el","parentElement","classList","add","login","then","data","totpmissingkey","totpdisabled","cn","url","continueLogin","msg","value","string","error","errorMessage","grace","l","expire","Math","round","passwordexpired","restoreLogin","passwordRecoveryInfo","verificationCode","passwordRecoveryAbort","href","reload","showAbout","$event","AboutDialogController","closeDialog","hide","show","targetEvent","templateUrl","controller","controllerAs","$inject","changeLanguage","ApplicationBaseURL","hello","form","canChangePassword","$setValidity","isInPasswordRecoveryMode","changePassword","mode","secretQuestionLabel","secretQuestion","obfuscatedRecoveryEmail","passwordRecoveryEmail","passwordRecoveryCheck","usernameChanged","clearTimeout","setTimeout","mailDomain","changePasswordVisibility","field","getElementById","type","innerHTML"],"mappings":"AAEA,CAAA,WACE,aAEAA,QAAQC,OAAO,cAAe,CAAC,cAAe,sBAAsB,EAOpE,SAASC,EAAgBC,EAAQC,EAASC,EAAUC,EAAQC,EAAWC,EAAgBC,EAAOC,GAC5F,IAAIC,EAAKC,KAETA,KAAKC,QAAU,WACbD,KAAKE,MAAQ,CACXC,SAAUX,EAAQY,eAClBC,SAAU,KACVC,OAAQ,KACRC,cAAenB,QAAQoB,UAAUhB,EAAQY,cAAc,GAAqC,EAAhCZ,EAAQY,eAAeK,MACrF,EAEI,cAAcC,KAAKlB,EAAQmB,SAASC,MAAM,IAC5CZ,KAAKE,MAAMW,SAAWrB,EAAQqB,UAChCb,KAAKc,WAAa,CAAA,EAGlBd,KAAKe,wBAA0B,SAG/Bf,KAAKgB,UAAY,CAAEC,YAAa,KAAMC,wBAAyB,KAAMC,YAAa,KAAMC,QAAS,CAAA,CAAM,EAGvGpB,KAAKqB,iBAAmB,CACtBC,wBAAyB,CAAA,EACzBC,4BAA6B,KAC7BC,yBAA0B,KAC1BC,qBAAsB,KACtBC,+BAAgC,KAChCC,sBAAuB,KACvBC,0BAA2B,KAC3BC,mCAAoC,KACpCC,2BAA4B,KAC5BC,WAAY,CAAA,CACd,EAGA/B,KAAKgC,UAAY,CAAA,EACjBvC,EAAS,WACPM,EAAGiC,UAAY,CAAA,EAEf,IAAMC,EAAcC,OAAOvB,SAASC,OAEpCuB,IAAIC,EADc,IAAIC,gBAAgBJ,CAAW,EAC3BK,IAAI,OAAO,EAE7B,EAAIJ,OAAOvB,SAAS4B,SAASC,QAAQ,uBAAuB,GAAKJ,EAK/D,KAHEK,GADNL,EAAQA,EAAMM,QAAQ,MAAO,EAAE,GACNC,MAAM,GAAG,GAGblC,SACnBV,EAAGsB,iBAAiBM,sBAAwBS,EACtCQ,EAAOC,KAAKC,MAAMC,KAAKN,EAAW,EAAE,CAAC,EAC3C1C,EAAGG,MAAMC,SAAWyC,EAAKzC,SACzBJ,EAAGG,MAAMI,OAASsC,EAAKtC,OACvBP,EAAGsB,iBAAiBM,sBAAwBS,EAC5CrC,EAAGsB,iBAAiBI,qBAAuB,iBAC3C1B,EAAGsB,iBAAiBC,wBAA0B,CAAA,EAE9CvB,EAAGe,WAAa,iBAChBf,EAAGiC,UAAY,CAAA,EACflC,EAAS,cAAc,GAIzBC,EAAGiD,gCAAgC,EAIgB,EAAjDC,SAASC,iBAAiB,YAAY,EAAEzC,QAC1CwC,SAASC,iBAAiB,YAAY,EAAEC,QAAQ,IAC9CC,EAAGC,cAAcC,UAAUC,IAAI,oBAAoB,CACrD,CAAC,CAEJ,EAAG,GAAG,CAET,EAEAvD,KAAKwD,MAAQ,WAmEX,OAlEAzD,EAAGe,WAAa,iBAChBlB,EAAe4D,MAAMzD,EAAGG,KAAK,EAC1BuD,KAAK,SAASC,GAETA,EAAKC,gBACP5D,EAAGe,WAAa,WAChBjB,EAAM,UAAU,GAET6D,EAAKE,cACZ7D,EAAGe,WAAa,eAChBf,EAAG8D,GAAKH,EAAKG,GACb9D,EAAG+D,IAAMJ,EAAKI,MAGd/D,EAAGe,WAAa,SAChBf,EAAG8D,GAAKH,EAAKG,GACb9D,EAAG+D,IAAMJ,EAAKI,IAGdrE,EAAS,WACPM,EAAGgE,cAAc,CACnB,EAAG,GAAI,EAEX,EAAG,SAASC,GAGV,IAYMC,EAGFC,EAjBJnE,EAAGe,WAAa,QAEZkD,EAAIG,MACNpE,EAAGqE,aAAeJ,EAAIG,MAEH,EAAZH,EAAIK,OAEXtE,EAAGe,WAAa,qBAChBf,EAAG8D,GAAKG,EAAIH,GACZ9D,EAAG+D,IAAME,EAAIF,IACb/D,EAAGqE,aAAeE,EAAE,sHAAuHN,EAAIK,KAAK,GAEhI,EAAbL,EAAIO,QAKTL,EAFe,MAAbF,EAAIO,QACNN,EAAQO,KAAKC,MAAMT,EAAIO,OAAO,KAAK,EAC1BD,EAAE,MAAM,GAEG,KAAbN,EAAIO,QACXN,EAAQO,KAAKC,MAAMT,EAAIO,OAAO,IAAI,EACzBD,EAAE,OAAO,GAEE,GAAbN,EAAIO,QACXN,EAAQO,KAAKC,MAAMT,EAAIO,OAAO,EAAE,EACvBD,EAAE,SAAS,IAGpBL,EAAQD,EAAIO,OACHD,EAAE,SAAS,GAEtBvE,EAAGe,WAAa,qBAChBf,EAAG8D,GAAKG,EAAIH,GACZ9D,EAAG+D,IAAME,EAAIF,IACb/D,EAAGqE,aAAeE,EAAE,iDAAkDL,EAAOC,CAAM,GAE5EF,EAAIU,kBACX3E,EAAGe,WAAa,iBAChBf,EAAG+D,IAAME,EAAIF,IAGjB,CAAC,EACI,CAAA,CACT,EAEA9D,KAAK2E,aAAe,WAClB5E,EAAGiC,UAAY,CAAA,EACX,mBAAqBjC,EAAGsB,iBAAiBI,sBAC3C3B,EAAS,cAAc,EACvBC,EAAG6E,qBAAqB,IAExB,OAAO7E,EAAGG,MAAM2E,iBAChB9E,EAAG+E,sBAAsB,EAE7B,EAEA9E,KAAK+D,cAAgB,WACfvE,EAAQmB,SAASoE,OAAShF,EAAG+D,IAC/BtE,EAAQmB,SAASqE,OAAO,CAAA,CAAI,EAE5BxF,EAAQmB,SAASoE,KAAOhF,EAAG+D,GAC/B,EAEA9D,KAAKiF,UAAY,SAASC,GAQxB,SAASC,EAAsBxF,GAC7BK,KAAKoF,YAAc,WACjBzF,EAAU0F,KAAK,CACjB,CACF,CAXA1F,EAAU2F,KAAK,CACbC,YAAaL,EACbM,YAAa,gBACbC,WAAYN,EACZO,aAAc,OAChB,CAAC,EACDP,EAAsBQ,QAAU,CAAC,YAMnC,EAEA3F,KAAK4F,eAAiB,SAASV,GAE7B1F,EAAQmB,SAASoE,KAAOc,mBAAqB,kBAAoB7F,KAAKE,MAAMW,QAC9E,EAEAb,KAAK8F,MAAQ,SAAUC,GACrB,MAAO,CAAA,CACT,EAEA/F,KAAKgG,kBAAoB,SAASD,GAChC,OAAI/F,KAAKgB,UAAUE,yBAA2BlB,KAAKgB,UAAUE,wBAAwBT,QACjFT,KAAKgB,UAAUC,aAAejB,KAAKgBLine truncated
+7 -1
View File
@@ -76,8 +76,14 @@
} else {
vm.retrievePasswordRecoveryEnabled();
}
}, 100);
// Manage autofill
if (document.querySelectorAll('*:autofill').length > 0) {
document.querySelectorAll('*:autofill').forEach((el) => {
el.parentElement.classList.add("md-input-has-value");
});
}
}, 100);
};