mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-05 08:34:30 +00:00
feat(password-recovery): Add password recovery with secret question or secondary email
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* JavaScript for MainUI (SOGoRootPage) */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular.module('SOGo.MainUI', ['SOGo.Common', 'SOGo.Authentication']);
|
||||
const PASSWORD_RECOVERY_TIMER_MS = 2000;
|
||||
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
LoginController.$inject = ['$scope', '$window', '$timeout', 'Dialog', '$mdDialog', 'Authentication', 'sgFocus'];
|
||||
function LoginController($scope, $window, $timeout, Dialog, $mdDialog, Authentication, focus) {
|
||||
LoginController.$inject = ['$scope', '$window', '$timeout', 'Dialog', '$mdDialog', 'Authentication', 'sgFocus', 'sgRippleClick'];
|
||||
function LoginController($scope, $window, $timeout, Dialog, $mdDialog, Authentication, focus, rippleDo) {
|
||||
var vm = this;
|
||||
|
||||
this.$onInit = function() {
|
||||
this.$onInit = function () {
|
||||
this.creds = {
|
||||
username: $window.cookieUsername,
|
||||
password: null,
|
||||
@@ -31,9 +31,53 @@
|
||||
// Password policy - change expired password
|
||||
this.passwords = { newPassword: null, newPasswordConfirmation: null, oldPassword: null };
|
||||
|
||||
// Password recovery
|
||||
this.passwordRecovery = {
|
||||
passwordRecoveryEnabled: false,
|
||||
passwordRecoveryQuestionKey: null,
|
||||
passwordRecoveryQuestion: null,
|
||||
passwordRecoveryMode: null,
|
||||
passwordRecoveryQuestionAnswer: null,
|
||||
passwordRecoveryToken: null,
|
||||
passwordRecoveryLinkTimer: null,
|
||||
passwordRecoverySecondaryEmailText: null,
|
||||
passwordRecoveryMailDomain: null
|
||||
};
|
||||
|
||||
// Show login once everything is initialized
|
||||
this.showLogin = false;
|
||||
$timeout(function() { vm.showLogin = true; }, 100);
|
||||
$timeout(function () {
|
||||
vm.showLogin = true;
|
||||
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
let token = urlParams.get('token');
|
||||
|
||||
if (0 < window.location.pathname.indexOf("passwordRecoveryEmail") && token) {
|
||||
token = token.replace(/\//g, ''); // remove trailing '/'
|
||||
const tokenArray = token.split(".");
|
||||
|
||||
// Retrieve info from token
|
||||
if (3 === tokenArray.length) {
|
||||
vm.passwordRecovery.passwordRecoveryToken = token;
|
||||
const info = JSON.parse(atob(tokenArray[1]));
|
||||
vm.creds.username = info.username;
|
||||
vm.creds.domain = info.domain;
|
||||
vm.passwordRecovery.passwordRecoveryToken = token;
|
||||
vm.passwordRecovery.passwordRecoveryMode = "SecondaryEmail";
|
||||
vm.passwordRecovery.passwordRecoveryEnabled = true;
|
||||
|
||||
vm.loginState = 'passwordchange';
|
||||
vm.showLogin = false;
|
||||
rippleDo('loginContent');
|
||||
}
|
||||
|
||||
} else {
|
||||
vm.retrievePasswordRecoveryEnabled();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.login = function() {
|
||||
@@ -98,7 +142,7 @@
|
||||
vm.errorMessage = l('Your password is going to expire in %{0} %{1}.', value, string);
|
||||
}
|
||||
else if (msg.passwordexpired) {
|
||||
vm.loginState = 'passwordexpired';
|
||||
vm.loginState = 'passwordchange';
|
||||
vm.url = msg.url;
|
||||
}
|
||||
|
||||
@@ -109,6 +153,9 @@
|
||||
this.restoreLogin = function() {
|
||||
vm.loginState = false;
|
||||
delete vm.creds.verificationCode;
|
||||
if (vm.isInPasswordRecoveryMode()) {
|
||||
vm.passwordRecoveryAbort();
|
||||
}
|
||||
};
|
||||
|
||||
this.continueLogin = function() {
|
||||
@@ -138,6 +185,10 @@
|
||||
$window.location.href = ApplicationBaseURL + 'login?language=' + this.creds.language;
|
||||
};
|
||||
|
||||
this.hello = function (form) {
|
||||
return !true;
|
||||
}
|
||||
|
||||
this.canChangePassword = function(form) {
|
||||
if (this.passwords.newPasswordConfirmation && this.passwords.newPasswordConfirmation.length &&
|
||||
this.passwords.newPassword != this.passwords.newPasswordConfirmation) {
|
||||
@@ -150,14 +201,15 @@
|
||||
if (this.passwords.newPassword && this.passwords.newPassword.length > 0 &&
|
||||
this.passwords.newPasswordConfirmation && this.passwords.newPasswordConfirmation.length &&
|
||||
this.passwords.newPassword == this.passwords.newPasswordConfirmation &&
|
||||
this.passwords.oldPassword && this.passwords.oldPassword.length > 0)
|
||||
((this.isInPasswordRecoveryMode()) ||
|
||||
(!this.loginState && this.passwords.oldPassword && this.passwords.oldPassword.length > 0)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.changePassword = function() {
|
||||
Authentication.changePassword(this.creds.username, this.creds.domain, this.passwords.newPassword, this.passwords.oldPassword).then(function(data) {
|
||||
Authentication.changePassword(this.creds.username, this.creds.domain, this.passwords.newPassword, this.passwords.oldPassword, this.passwordRecovery.passwordRecoveryToken).then(function(data) {
|
||||
vm.loginState = 'message';
|
||||
vm.url = data.url;
|
||||
vm.errorMessage = l('The password was changed successfully.');
|
||||
@@ -167,6 +219,95 @@
|
||||
});
|
||||
};
|
||||
|
||||
this.passwordRecoveryInfo = function () {
|
||||
vm.loginState = 'passwordrecovery';
|
||||
Authentication.passwordRecovery(this.creds.username, this.creds.domain).then(function (data) {
|
||||
vm.passwordRecovery.passwordRecoveryMode = data.mode;
|
||||
if ('SecretQuestion' === data.mode) {
|
||||
vm.passwordRecovery.passwordRecoveryQuestion = data.secretQuestionLabel;
|
||||
vm.passwordRecovery.passwordRecoveryQuestionKey = data.secretQuestion;
|
||||
} else if ('SecondaryEmail' === data.mode) {
|
||||
vm.passwordRecovery.passwordRecoverySecondaryEmailText = l("A link will be sent to %{0}", data.obfuscatedRecoveryEmail);
|
||||
} else if ('Disabled' === data.mode) {
|
||||
vm.loginState = 'error';
|
||||
vm.errorMessage = l('No password recovery method has been defined for this user');
|
||||
}
|
||||
}, function (msg) {
|
||||
vm.loginState = 'error';
|
||||
vm.errorMessage = msg;
|
||||
});
|
||||
};
|
||||
|
||||
this.passwordRecoveryEmail = function () {
|
||||
Authentication.passwordRecoveryEmail(this.creds.username, this.creds.domain
|
||||
, this.passwordRecovery.passwordRecoveryMode
|
||||
, this.passwordRecovery.passwordRecoveryMailDomain).then(function () {
|
||||
vm.loginState = 'sendrecoverymail';
|
||||
}, function (msg) {
|
||||
vm.loginState = 'error';
|
||||
vm.errorMessage = msg;
|
||||
});
|
||||
};
|
||||
|
||||
this.passwordRecoveryCheck = function () {
|
||||
Authentication.passwordRecoveryCheck(this.creds.username, this.creds.domain
|
||||
, this.passwordRecovery.passwordRecoveryMode
|
||||
, this.passwordRecovery.passwordRecoveryQuestionKey
|
||||
, this.passwordRecovery.passwordRecoveryQuestionAnswer
|
||||
, this.passwordRecovery.passwordRecoveryMailDomain).then(function (token) {
|
||||
if ("SecretQuestion" == vm.passwordRecovery.passwordRecoveryMode) {
|
||||
vm.passwordRecovery.passwordRecoveryToken = token;
|
||||
vm.loginState = 'passwordchange';
|
||||
} else if ("SecondaryEmail" == vm.passwordRecovery.passwordRecoveryMode) {
|
||||
vm.loginState = 'sendrecoverymail';
|
||||
}
|
||||
}, function (msg) {
|
||||
vm.loginState = 'error';
|
||||
vm.errorMessage = msg;
|
||||
});
|
||||
};
|
||||
|
||||
this.isInPasswordRecoveryMode = function () {
|
||||
return (("SecretQuestion" == this.passwordRecovery.passwordRecoveryMode ||
|
||||
"SecondaryEmail" == this.passwordRecovery.passwordRecoveryMode) &&
|
||||
this.passwordRecovery.passwordRecoveryToken) ? true : false;
|
||||
};
|
||||
|
||||
this.passwordRecoveryAbort = function () {
|
||||
this.passwords = { newPassword: null, newPasswordConfirmation: null, oldPassword: null };
|
||||
this.loginState = false;
|
||||
this.passwordRecovery.passwordRecoveryEnabled = false;
|
||||
this.passwordRecovery.passwordRecoveryQuestion = null;
|
||||
this.passwordRecovery.passwordRecoveryMode = null;
|
||||
this.passwordRecovery.passwordRecoveryQuestionAnswer = null;
|
||||
this.passwordRecovery.passwordRecoveryToken = null;
|
||||
this.passwordRecovery.passwordRecoverySecondaryEmailText = null;
|
||||
this.passwordRecovery.passwordRecoveryMailDomain = null;
|
||||
$window.location.href = vm.url;
|
||||
};
|
||||
|
||||
this.usernameChanged = function () {
|
||||
if (this.passwordRecovery.passwordRecoveryLinkTimer) {
|
||||
clearTimeout(this.passwordRecovery.passwordRecoveryLinkTimer);
|
||||
}
|
||||
|
||||
this.passwordRecovery.passwordRecoveryLinkTimer = setTimeout(() => {
|
||||
vm.retrievePasswordRecoveryEnabled();
|
||||
this.passwordRecovery.passwordRecoveryLinkTimer = null;
|
||||
}, PASSWORD_RECOVERY_TIMER_MS);
|
||||
};
|
||||
|
||||
this.retrievePasswordRecoveryEnabled = function () {
|
||||
if (this.creds.username || this.creds.domain) {
|
||||
Authentication.passwordRecoveryEnabled(this.creds.username, this.creds.domain).then(function (mailDomain) {
|
||||
vm.passwordRecovery.passwordRecoveryMailDomain = mailDomain;
|
||||
vm.passwordRecovery.passwordRecoveryEnabled = true;
|
||||
}, function () {
|
||||
vm.passwordRecovery.passwordRecoveryEnabled = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
angular
|
||||
|
||||
Reference in New Issue
Block a user