Files
sogo/UI/WebServerResources/js/Common/Authentication.service.js

379 lines
14 KiB
JavaScript

/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for Authentication */
(function() {
/* jshint validthis: true */
'use strict';
angular.module('SOGo.Authentication', ['ngCookies'])
.constant('passwordPolicyConfig', {
PolicyPasswordChangeUnsupported: -3,
PolicyPasswordSystemUnknown: -2,
PolicyPasswordUnknown: -1,
PolicyPasswordExpired: 0,
PolicyAccountLocked: 1,
PolicyChangeAfterReset: 2,
PolicyPasswordModNotAllowed: 3,
PolicyMustSupplyOldPassword: 4,
PolicyInsufficientPasswordQuality: 5,
PolicyPasswordTooShort: 6,
PolicyPasswordTooYoung: 7,
PolicyPasswordInHistory: 8,
PolicyPasswordRecoveryFailed: 9,
PolicyPasswordRecoveryInvalidToken: 10,
PolicyNoError: 65535
})
.provider('Authentication', Authentication);
function Authentication() {
function redirectUrl(username, domain) {
var userName, address, baseAddress, parts, hostpart, protocol, newAddress;
userName = username;
if (domain)
userName += '@' + domain;
address = '' + window.location.href;
baseAddress = ApplicationBaseURL + encodeURIComponent(userName);
if (baseAddress[0] == '/') {
parts = address.split('/');
hostpart = parts[2];
protocol = parts[0];
baseAddress = protocol + '//' + hostpart + baseAddress;
}
if (address.startsWith(baseAddress) && !address.endsWith('/logoff'))
newAddress = address;
else
newAddress = baseAddress;
return newAddress;
}
this.$get = getService;
/**
* @ngInject
*/
getService.$inject = ['$q', '$http', '$cookies', 'passwordPolicyConfig'];
function getService($q, $http, $cookies, passwordPolicyConfig) {
var service;
service = {
login: function(data) {
var d = $q.defer(),
username = data.username,
password = data.password,
verificationCode = data.verificationCode,
domain = data.domain,
language,
rememberLogin = data.rememberLogin ? 1 : 0;
if (data.loginSuffix && !username.endsWith(data.loginSuffix)) {
username += loginSuffix;
domain = false;
}
if (data.language && data.language != 'WONoSelectionString') {
language = data.language;
}
$http({
method: 'POST',
url: '/SOGo/connect',
data: {
userName: username,
password: password,
verificationCode: verificationCode,
domain: domain,
language: language,
rememberLogin: rememberLogin
}
}).then(function(response) {
var data = response.data;
// Make sure browser's cookies are enabled
if (navigator && !navigator.cookieEnabled) {
d.reject({error: l('cookiesNotEnabled')});
}
else {
// Check for TOTP
if (typeof data.totpMissingKey != 'undefined' && response.status == 202) {
d.resolve({totpmissingkey: 1});
}
else if (typeof data.totpDisabled != 'undefined') {
d.resolve({
cn: data.cn,
url: redirectUrl(data.username, domain),
totpdisabled: 1
});
}
// Check password policy
else if (typeof data.expire != 'undefined' && typeof data.grace != 'undefined') {
if (data.expire < 0 && data.grace > 0) {
d.reject({
cn: data.cn,
url: redirectUrl(username, domain),
grace: data.grace
});
} else if (data.expire > 0 && data.grace == -1) {
d.reject({
cn: data.cn,
url: redirectUrl(username, domain),
expire: data.expire
});
}
else {
d.resolve({
cn: data.cn,
url: redirectUrl(data.username, domain)
});
}
}
else {
d.resolve({ url: redirectUrl(data.username, domain) });
}
}
}, function(error) {
var response, perr, data = error.data;
if (data && data.totpInvalidKey) {
response = {error: l('You provided an invalid TOTP key.')};
}
else if (data && angular.isDefined(data.LDAPPasswordPolicyError)) {
perr = data.LDAPPasswordPolicyError;
if (perr == passwordPolicyConfig.PolicyNoError) {
response = {error: l('Wrong username or password.')};
}
else if (perr == passwordPolicyConfig.PolicyAccountLocked) {
response = {error: l('Your account was locked due to too many failed attempts.')};
}
else if (perr == passwordPolicyConfig.PolicyPasswordExpired ||
perr == passwordPolicyConfig.PolicyChangeAfterReset) {
response = {
passwordexpired: 1,
userPolicies: data.additionalInfos.userPolicies,
url: redirectUrl(username, domain)
};
}
else if (perr == passwordPolicyConfig.PolicyChangeAfterReset) {
response = {
passwordexpired: 1,
userPolicies: data.additionalInfos.userPolicies,
url: redirectUrl(username, domain)
};
} else if (perr == passwordPolicyConfig.PolicyInsufficientPasswordQuality) {
response = {
passwordexpired: 2,
userPolicies: data.additionalInfos.userPolicies,
url: redirectUrl(username, domain)
};
}
else {
response = {error: l('Login failed due to unhandled error case: ') + perr};
}
}
else {
response = {error: l('Unhandled error response')};
}
d.reject(response);
});
return d.promise;
}, // login: function(data) { ...
loginName: function(data) {
var d = $q.defer(),
username = data.username,
language;
if (data.language && data.language != 'WONoSelectionString') {
language = data.language;
}
$http({
method: 'POST',
url: '/SOGo/connectName?userName='+username,
// data: JSON.stringify({userName: username}),
data: {userName: username},
// headers: {
// //'Content-Type': undefined
// //'Content-Type': "application/x-www-form-urlencoded"
// 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8'
// }
}).then(function(response) {
var data = response.data;
// Make sure browser's cookies are enabled
if (navigator && !navigator.cookieEnabled) {
d.reject({error: l('cookiesNotEnabled')});
}
else {
if(data.redirect) {
//Redirection in case of openID
d.resolve({ url: data.redirect });
}
}
}, function(error) {
var response, perr, data = error.data;
d.reject(response);
});
return d.promise;
},
changePassword: function(userName, domain, newPassword, oldPassword, token) {
var d = $q.defer(),
xsrfCookie = $cookies.get('XSRF-TOKEN');
$cookies.remove('XSRF-TOKEN', {path: '/SOGo/'});
$http({
method: 'POST',
url: '/SOGo/so/changePassword',
headers: {
'X-XSRF-TOKEN' : xsrfCookie
},
data: { userName: userName, newPassword: newPassword, oldPassword: oldPassword, token: token }
}).then(function (response) {
if (response && response.data && response.data.username) {
d.resolve({ url: redirectUrl(response.data.username, domain) });
} else {
d.resolve({ url: redirectUrl(userName, domain) });
}
}, function(response) {
var error,
data = response.data,
perr = data.LDAPPasswordPolicyError;
if (!perr) {
perr = passwordPolicyConfig.PolicyPasswordSystemUnknown;
error = _("Unhandled error response");
}
else if (perr == passwordPolicyConfig.PolicyNoError ||
perr == passwordPolicyConfig.PolicyPasswordUnknown) {
error = l("Password change failed");
} else if (perr == passwordPolicyConfig.PolicyPasswordModNotAllowed) {
error = l("Password change failed - Permission denied");
} else if (perr == passwordPolicyConfig.PolicyInsufficientPasswordQuality) {
error = l("Password change failed - Insufficient password quality");
} else if (perr == passwordPolicyConfig.PolicyPasswordTooShort) {
error = l("Password change failed - Password is too short");
} else if (perr == passwordPolicyConfig.PolicyPasswordTooYoung) {
error = l("Password change failed - Password is too young");
} else if (perr == passwordPolicyConfig.PolicyPasswordInHistory) {
error = l("Password change failed - Password is in history");
} else if (perr == passwordPolicyConfig.PolicyPasswordRecoveryInvalidToken) {
error = l("Invalid token. Could not change password");
} else {
error = l("Unhandled policy error: %{0}").formatted(perr);
perr = passwordPolicyConfig.PolicyPasswordUnknown;
}
// Restore the cookie
$cookies.put('XSRF-TOKEN', xsrfCookie, {path: '/SOGo/'});
d.reject(error);
});
return d.promise;
},
passwordRecovery: function (userName, domain) {
var self = this;
var d = $q.defer(),
xsrfCookie = $cookies.get('XSRF-TOKEN');
$cookies.remove('XSRF-TOKEN', { path: '/SOGo/' });
$http({
method: 'POST',
url: '/SOGo/so/passwordRecovery',
headers: {
'X-XSRF-TOKEN': xsrfCookie
},
data: { userName: userName, domain: domain }
}).then(function (response) {
d.resolve(Object.assign(
{ url: redirectUrl(userName, domain) },
response.data,
'SecretQuestion' === response.data.mode ? { secretQuestionLabel: l('passwordRecovery_' + response.data.secretQuestion) } : {},
'SecondaryEmail' === response.data.mode ? { obfuscatedRecoveryEmail: response.data.obfuscatedSecondaryEmail } : {}
));
}, function () {
// Restore the cookie
$cookies.put('XSRF-TOKEN', xsrfCookie, { path: '/SOGo/' });
d.reject(l("Unhandled policy error: %{0}").formatted(passwordPolicyConfig.PolicyPasswordRecoveryFailed));
});
return d.promise;
},
passwordRecoveryEmail: function (userName, domain, mode, mailDomain) {
var self = this;
var d = $q.defer(),
xsrfCookie = $cookies.get('XSRF-TOKEN');
$cookies.remove('XSRF-TOKEN', { path: '/SOGo/' });
$http({
method: 'POST',
url: '/SOGo/so/passwordRecoveryEmail',
headers: {
'X-XSRF-TOKEN': xsrfCookie
},
data: { userName: userName, domain: domain, mode: mode, mailDomain: mailDomain }
}).then(function (response) {
d.resolve(response.data.jwt);
}, function (response) {
// Restore the cookie
$cookies.put('XSRF-TOKEN', xsrfCookie, { path: '/SOGo/' });
d.reject(l(response.data));
});
return d.promise;
},
passwordRecoveryCheck: function (userName, domain, mode, question, answer, mailDomain) {
var self = this;
var d = $q.defer(),
xsrfCookie = $cookies.get('XSRF-TOKEN');
$cookies.remove('XSRF-TOKEN', { path: '/SOGo/' });
$http({
method: 'POST',
url: '/SOGo/so/passwordRecoveryCheck',
headers: {
'X-XSRF-TOKEN': xsrfCookie
},
data: { userName: userName, domain: domain, mode: mode, question: question, answer: answer, mailDomain: mailDomain }
}).then(function (response) {
d.resolve(response.data.jwt);
}, function (response) {
// Restore the cookie
$cookies.put('XSRF-TOKEN', xsrfCookie, { path: '/SOGo/' });
d.reject(l(response.data));
});
return d.promise;
},
passwordRecoveryEnabled: function (userName, domain) {
var self = this;
var d = $q.defer();
$http({
method: 'POST',
url: '/SOGo/so/passwordRecoveryEnabled',
data: { userName: userName, domain: domain }
}).then(function (response) {
d.resolve(response.data.domain);
}, function () {
d.reject();
});
return d.promise;
}
};
return service;
}
}
})();