Viewing File: /usr/local/cpanel/share/libraries/cjt2/src/services/passwordStrengthService.js
/*
# cjt/services/passwordStrengthService.js Copyright(c) 2020 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
[
// Libraries
"angular",
"lodash",
// CJT
"cjt/core",
"cjt/util/locale",
"cjt/util/performance"
],
function(angular, _, CJT, LOCALE, performance) {
var module = angular.module("cjt2.services.passwordStrength", []);
var url = CJT.securityToken + (CJT.isUnprotected() ? "/unprotected" : "/backend" ) + "/passwordstrength.cgi";
var lastRequest = null;
var memoizedPasswordStrengths = {};
/**
* Setup the password strength API service
*/
module.factory("passwordStrength", [ "$q", "$http", "$rootScope", function($q, $http, $rootScope) {
/**
* Broadcast the event
*
* @private
* @method _broadcast
* @param {String} id
* @param {String} password
* @param {Number} strength
*/
function _broadcast(id, password, strength) {
$rootScope.$broadcast("passwordStrengthChange", {
// Password field we are validating
id: id,
// For validators to pull apart.
password: password,
// Just let the other listeners know if the password is set
hasPassword: password && password.length > 0 ? true : false,
// Strength returned by the service
strength: strength
});
}
// return the factory interface
return {
/**
* Cancel the last pending request if it exists.
*
* @method cancelLastRequest
*/
cancelLastRequest: function() {
if (lastRequest) {
lastRequest.cancel();
lastRequest.deferred.reject({
canceled: true
});
CJT.debug("Canceled existing request");
lastRequest = null;
}
},
/**
* Checks if there are any pending requests for strength check.
*
* @method hasPendingRequest
* @return {Boolean} true if there are pending requests, false otherwise.
*/
hasPendingRequest: function() {
return lastRequest !== null;
},
/**
* Checks the strength of a password.
*
* @method checkPasswordStrength
* @param {String} id The unique id for the field being evaluated.
* @param {String} password The password to check.
* @return {Promise} A promise that resolves once the password strength is determined
* or rejects if it wasn't determined.
*/
checkPasswordStrength: function(id, password) {
// Cancel the last request if it exists
this.cancelLastRequest();
var deferred, canceler;
// Exit quickly if password is empty or undefined
if (angular.isUndefined(password) || password === "") {
_broadcast(id, password, 0);
deferred = $q.defer();
deferred.resolve({
status: 200,
strength: 0,
password: password,
id: id
});
return deferred.promise;
}
if (memoizedPasswordStrengths.hasOwnProperty(password)) {
_broadcast(id, password, memoizedPasswordStrengths[password]);
deferred = $q.defer();
deferred.resolve({
status: 200,
strength: memoizedPasswordStrengths[password],
password: password,
id: id
});
return deferred.promise;
}
// Setup and stash key items from the last request for cancellation purposes
canceler = $q.defer();
deferred = $q.defer();
lastRequest = {
cancel: function() {
canceler.resolve();
},
deferred: deferred
};
// Prepare the postAsForm arguments
var request = {
url: url,
data: {
password: password
},
config: {
timeout: canceler.promise.then(function() {
var stop = performance.now();
CJT.debug("Call to cgi password strength service canceled " + (stop - start) + " milliseconds.");
})
}
};
var start = performance.now();
var strength = 0;
$http.postAsForm(request.url, request.data, request.config).then(
function(response) {
var stop = performance.now();
CJT.debug("Call to cgi password strength service " + (stop - start) + " milliseconds.");
// We can't resolve the promise if there's no strength returned
if ( !angular.isUndefined(response.data.strength) ) {
memoizedPasswordStrengths[password] = response.data.strength;
strength = response.data.strength;
deferred.resolve({
status: 200,
strength: strength,
password: password,
id: id
});
} else {
deferred.reject({
statusText: "Unspecified API Error", // HTTP status messages aren't localized
status: response.status,
strength: strength,
password: password,
id: id
});
}
},
// HTTP status other than 200
function(error) {
deferred.reject({
statusText: error.statusText,
status: error.status,
strength: strength,
password: password,
id: id
});
}
).finally(function() {
// Done processing so clear the last request
lastRequest = null;
_broadcast(id, password, strength);
});
return deferred.promise;
}
};
}]);
return {
url: url
};
}
);
Back to Directory
File Manager