refactor(client): Remove the password strength checker. (#4903) r=vladikoff
Not attached to any PR.
This commit is contained in:
Родитель
9b296fb9f7
Коммит
4786c1fcb1
|
@ -40,8 +40,7 @@ require.config({
|
|||
],
|
||||
requireOnDemand: [
|
||||
'fxaClient',
|
||||
'jwcrypto',
|
||||
'passwordcheck'
|
||||
'jwcrypto'
|
||||
],
|
||||
// the sriify task will replace sriConfig for production
|
||||
// DO NOT EDIT BELOW HERE
|
||||
|
@ -85,7 +84,6 @@ require.config({
|
|||
modal: '../bower_components/jquery-modal/jquery.modal',
|
||||
moment: '../bower_components/moment/moment',
|
||||
mustache: '../bower_components/mustache/mustache',
|
||||
passwordcheck: '../bower_components/fxa-password-strength-checker/build/fxa-password-strength-checker',
|
||||
'p-promise': '../bower_components/p/p',
|
||||
raven: '../bower_components/raven-js/dist/raven',
|
||||
sinon: '../bower_components/sinon/lib/sinon',
|
||||
|
|
|
@ -13,7 +13,6 @@ define(function (require, exports, module) {
|
|||
const Notifier = require('lib/channels/notifier');
|
||||
const PasswordMixin = require('views/mixins/password-mixin');
|
||||
const PasswordResetMixin = require('views/mixins/password-reset-mixin');
|
||||
const PasswordStrengthMixin = require('views/mixins/password-strength-mixin');
|
||||
const ResendMixin = require('views/mixins/resend-mixin')();
|
||||
const ServiceMixin = require('views/mixins/service-mixin');
|
||||
const Template = require('stache!templates/complete_reset_password');
|
||||
|
@ -168,7 +167,6 @@ define(function (require, exports, module) {
|
|||
FlowEventsMixin,
|
||||
PasswordMixin,
|
||||
PasswordResetMixin,
|
||||
PasswordStrengthMixin,
|
||||
ResendMixin,
|
||||
ServiceMixin
|
||||
);
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Plugin to display hints for passwords,
|
||||
* hints change as the user types
|
||||
*/
|
||||
|
||||
define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
const { t } = require('views/base');
|
||||
const Tooltip = require('views/tooltip');
|
||||
|
||||
// this link is not suitable for L10N and should be available in only `en` locales.
|
||||
const CHECK_PASSWORD_FIELD_SELECTOR = '.check-password';
|
||||
const INPUT_HELP_FOCUSED = '.input-help-focused';
|
||||
const TOOLTIP_MESSAGES = {
|
||||
FOCUS_PROMPT_MESSAGE: t('8 characters minimum, but longer if you plan to sync passwords.'),
|
||||
INITIAL_PROMPT_MESSAGE: t('A strong, unique password will keep your Firefox data safe from intruders.'),
|
||||
WARNING_PROMPT_MESSAGE: t('This is a common password; please consider another one.')
|
||||
};
|
||||
|
||||
const PasswordPromptMixin = {
|
||||
// only the .check-password fields will be checked
|
||||
events: {
|
||||
'blur .check-password': 'onPasswordBlur',
|
||||
'focus .check-password': 'onInputFocus',
|
||||
'keyup .check-password': 'onInputKeyUp'
|
||||
},
|
||||
|
||||
afterRender () {
|
||||
this.updateFormValueChanges();
|
||||
},
|
||||
|
||||
displayPasswordInitialPrompt (inputEl) {
|
||||
this.$(inputEl).siblings(INPUT_HELP_FOCUSED).html(this.translate(TOOLTIP_MESSAGES.INITIAL_PROMPT_MESSAGE));
|
||||
this._logPromptExperimentEvent('INITIAL_PROMPT_MESSAGE');
|
||||
},
|
||||
|
||||
displayPasswordFocusPrompt (inputEl) {
|
||||
this.$(inputEl).siblings(INPUT_HELP_FOCUSED).html(this.translate(TOOLTIP_MESSAGES.FOCUS_PROMPT_MESSAGE));
|
||||
this._logPromptExperimentEvent('FOCUS_PROMPT_MESSAGE');
|
||||
},
|
||||
|
||||
displayPasswordWarningPrompt () {
|
||||
const promptContent =
|
||||
this.translate(TOOLTIP_MESSAGES.WARNING_PROMPT_MESSAGE);
|
||||
|
||||
const tooltip = new Tooltip({
|
||||
dismissible: false,
|
||||
extraClassNames: 'tooltip-suggest tooltip-warning',
|
||||
invalidEl: this.$(CHECK_PASSWORD_FIELD_SELECTOR),
|
||||
message: promptContent
|
||||
});
|
||||
tooltip.render();
|
||||
this._logPromptExperimentEvent('WARNING_PROMPT_MESSAGE');
|
||||
},
|
||||
|
||||
showPasswordPrompt (inputEl) {
|
||||
const length = this.$(inputEl).val().length;
|
||||
if (length === 0) {
|
||||
this.displayPasswordInitialPrompt(inputEl);
|
||||
} else {
|
||||
this.displayPasswordFocusPrompt(inputEl);
|
||||
}
|
||||
},
|
||||
|
||||
onInputFocus (event) {
|
||||
this.showPasswordPrompt(event.currentTarget);
|
||||
},
|
||||
|
||||
onInputKeyUp (event) {
|
||||
this.showPasswordPrompt(event.currentTarget);
|
||||
},
|
||||
|
||||
onPasswordBlur () {
|
||||
const password = this.getElementValue(CHECK_PASSWORD_FIELD_SELECTOR);
|
||||
this.checkPasswordStrength(password);
|
||||
},
|
||||
|
||||
_logPromptExperimentEvent (eventNameSuffix) {
|
||||
const eventName = 'experiment.pw_prompt.' + eventNameSuffix.toLowerCase();
|
||||
this.logEventOnce(eventName);
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines if user is using an English locale.
|
||||
* @returns {Boolean}
|
||||
* @private
|
||||
*/
|
||||
_isEnglishLocale () {
|
||||
return !! (this.lang && this.lang.indexOf('en') === 0);
|
||||
},
|
||||
|
||||
// Constants, exposed for testing
|
||||
CHECK_PASSWORD_FIELD_SELECTOR: CHECK_PASSWORD_FIELD_SELECTOR,
|
||||
INPUT_HELP_FOCUSED: INPUT_HELP_FOCUSED,
|
||||
TOOLTIP_MESSAGES: TOOLTIP_MESSAGES
|
||||
};
|
||||
module.exports = PasswordPromptMixin;
|
||||
});
|
|
@ -1,106 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
const _ = require('underscore');
|
||||
const p = require('lib/promise');
|
||||
const requireOnDemand = require('lib/require-on-demand');
|
||||
const Url = require('lib/url');
|
||||
const PasswordPromptMixin = require('views/mixins/password-prompt-mixin');
|
||||
|
||||
var PasswordStrengthMixin = {
|
||||
|
||||
initialize (options) {
|
||||
this._able = options.able;
|
||||
},
|
||||
|
||||
_isPasswordStrengthCheckEnabledValue: undefined,
|
||||
isPasswordStrengthCheckEnabled () {
|
||||
if (_.isUndefined(this._isPasswordStrengthCheckEnabledValue)) {
|
||||
var abData = {
|
||||
// the window parameter will override any ab testing features
|
||||
forcePasswordStrengthCheck: Url.searchParam('passwordStrengthCheck', this.window.location.search),
|
||||
isMetricsEnabledValue: this.metrics.isCollectionEnabled(),
|
||||
uniqueUserId: this.user.get('uniqueUserId')
|
||||
};
|
||||
|
||||
this._isPasswordStrengthCheckEnabledValue =
|
||||
this._able.choose('passwordStrengthCheckEnabled', abData);
|
||||
|
||||
if (this._isPasswordStrengthCheckEnabledValue) {
|
||||
this._logStrengthExperimentEvent('enabled');
|
||||
}
|
||||
}
|
||||
return this._isPasswordStrengthCheckEnabledValue;
|
||||
},
|
||||
|
||||
_passwordStrengthCheckerPromise: undefined,
|
||||
getPasswordStrengthChecker () {
|
||||
// returns a promise that resolves once the library is loaded.
|
||||
if (! this._passwordStrengthCheckerPromise) {
|
||||
this._passwordStrengthCheckerPromise = requireOnDemand('passwordcheck')
|
||||
// Log any failures loading the script
|
||||
.fail(this.logError.bind(this))
|
||||
.then((PasswordCheck) => {
|
||||
return new PasswordCheck();
|
||||
});
|
||||
}
|
||||
return this._passwordStrengthCheckerPromise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check the password strength. Returns a promise that resolves
|
||||
* when the check is complete. Promise resolves to `DISABLED` if
|
||||
* password strength checker is disabled.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* view.checkPasswordStrength(password)
|
||||
* .then(function (status) {
|
||||
* // do something with the status
|
||||
* });
|
||||
*
|
||||
* @method checkPasswordStrength
|
||||
* @param {String} password
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
checkPasswordStrength (password) {
|
||||
if (! this.isPasswordStrengthCheckEnabled()) {
|
||||
return p('DISABLED');
|
||||
}
|
||||
|
||||
return this.getPasswordStrengthChecker()
|
||||
.then((passwordStrengthChecker) => {
|
||||
var deferred = p.defer();
|
||||
passwordStrengthChecker(password, (passwordCheckStatus) => {
|
||||
passwordCheckStatus = passwordCheckStatus || 'UNKNOWN';
|
||||
|
||||
if (passwordCheckStatus === 'BLOOMFILTER_HIT' ||
|
||||
passwordCheckStatus === 'BLOOMFILTER_MISS') {
|
||||
this._logStrengthExperimentEvent('bloomfilter_used');
|
||||
}
|
||||
if (passwordCheckStatus === 'BLOOMFILTER_HIT' ||
|
||||
passwordCheckStatus === 'ALL_LETTERS_OR_NUMBERS') {
|
||||
// display the warning prompt only if the password is ALL_LETTERS_OR_NUMBERS
|
||||
// or password is found in list of common passwords
|
||||
this.displayPasswordWarningPrompt();
|
||||
}
|
||||
this._logStrengthExperimentEvent(passwordCheckStatus);
|
||||
|
||||
deferred.resolve(passwordCheckStatus);
|
||||
});
|
||||
return deferred.promise;
|
||||
});
|
||||
},
|
||||
|
||||
_logStrengthExperimentEvent (eventNameSuffix) {
|
||||
var eventName = 'experiment.pw_strength.' + eventNameSuffix.toLowerCase();
|
||||
this.logViewEvent(eventName);
|
||||
}
|
||||
};
|
||||
module.exports = _.extend(PasswordStrengthMixin, PasswordPromptMixin);
|
||||
});
|
|
@ -13,7 +13,6 @@ define(function (require, exports, module) {
|
|||
const FormView = require('views/form');
|
||||
const ExperimentMixin = require('views/mixins/experiment-mixin');
|
||||
const PasswordMixin = require('views/mixins/password-mixin');
|
||||
const PasswordStrengthMixin = require('views/mixins/password-strength-mixin');
|
||||
const ServiceMixin = require('views/mixins/service-mixin');
|
||||
const SettingsPanelMixin = require('views/mixins/settings-panel-mixin');
|
||||
const Template = require('stache!templates/settings/change_password');
|
||||
|
@ -71,7 +70,6 @@ define(function (require, exports, module) {
|
|||
View,
|
||||
ExperimentMixin,
|
||||
PasswordMixin,
|
||||
PasswordStrengthMixin,
|
||||
FloatingPlaceholderMixin,
|
||||
SettingsPanelMixin,
|
||||
ServiceMixin,
|
||||
|
|
|
@ -18,7 +18,6 @@ define(function (require, exports, module) {
|
|||
const MigrationMixin = require('views/mixins/migration-mixin');
|
||||
const p = require('lib/promise');
|
||||
const PasswordMixin = require('views/mixins/password-mixin');
|
||||
const PasswordStrengthMixin = require('views/mixins/password-strength-mixin');
|
||||
const ResumeTokenMixin = require('views/mixins/resume-token-mixin');
|
||||
const ServiceMixin = require('views/mixins/service-mixin');
|
||||
const SignedInNotificationMixin = require('views/mixins/signed-in-notification-mixin');
|
||||
|
@ -120,12 +119,6 @@ define(function (require, exports, module) {
|
|||
}.bind(this));
|
||||
}
|
||||
|
||||
if (this.isPasswordStrengthCheckEnabled()) {
|
||||
// load the password strength checker early so the user does
|
||||
// not need to wait once they fill out the password.
|
||||
this.getPasswordStrengthChecker();
|
||||
}
|
||||
|
||||
return FormView.prototype.afterVisible.call(this);
|
||||
},
|
||||
|
||||
|
@ -399,7 +392,6 @@ define(function (require, exports, module) {
|
|||
FlowBeginMixin,
|
||||
MigrationMixin,
|
||||
PasswordMixin,
|
||||
PasswordStrengthMixin,
|
||||
ResumeTokenMixin,
|
||||
ServiceMixin,
|
||||
SignInMixin,
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
const $ = require('jquery');
|
||||
const { assert } = require('chai');
|
||||
const Cocktail = require('cocktail');
|
||||
const Notifier = require('lib/channels/notifier');
|
||||
const p = require('lib/promise');
|
||||
const PasswordPromptMixin = require('views/mixins/password-prompt-mixin');
|
||||
const PasswordStrengthMixin = require('views/mixins/password-strength-mixin');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const FormView = require('views/form');
|
||||
const Template = require('stache!templates/test_template');
|
||||
const Translator = require('lib/translator');
|
||||
|
||||
const TestView = FormView.extend({
|
||||
template: Template
|
||||
});
|
||||
|
||||
const viewOpts = {
|
||||
notifier: new Notifier(),
|
||||
translator: new Translator({forceEnglish: true})
|
||||
};
|
||||
|
||||
Cocktail.mixin(
|
||||
TestView,
|
||||
PasswordPromptMixin,
|
||||
PasswordStrengthMixin
|
||||
);
|
||||
|
||||
const TOOLTIP_SELECTOR = '.tooltip-warning';
|
||||
|
||||
|
||||
describe('views/mixins/password-prompt-mixin', function () {
|
||||
var view;
|
||||
|
||||
describe('showPasswordPrompt displays different prompts', function () {
|
||||
beforeEach(function () {
|
||||
view = new TestView(viewOpts);
|
||||
return view.render();
|
||||
});
|
||||
|
||||
it('displays the initial password prompt when password field is empty', function () {
|
||||
var password = '';
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).val(password);
|
||||
view.showPasswordPrompt(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR);
|
||||
assert.equal(
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).siblings(PasswordPromptMixin.INPUT_HELP_FOCUSED).html(),
|
||||
PasswordPromptMixin.TOOLTIP_MESSAGES.INITIAL_PROMPT_MESSAGE
|
||||
);
|
||||
});
|
||||
|
||||
it('displays the focused password prompt when password field is not empty', function () {
|
||||
var password = 's';
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).val(password);
|
||||
view.showPasswordPrompt(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR);
|
||||
assert.equal(
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).siblings(PasswordPromptMixin.INPUT_HELP_FOCUSED).html(),
|
||||
PasswordPromptMixin.TOOLTIP_MESSAGES.FOCUS_PROMPT_MESSAGE
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('event triggers call the correct methods', function () {
|
||||
beforeEach(function () {
|
||||
view = new TestView(viewOpts);
|
||||
sinon.spy(view, 'showPasswordPrompt');
|
||||
return view.render();
|
||||
});
|
||||
|
||||
it('onInputFocus calls showPasswordPrompt with the right password field', function () {
|
||||
var event = new $.Event('focus');
|
||||
event.currentTarget = PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR;
|
||||
view.onInputFocus(event);
|
||||
assert.isTrue(view.showPasswordPrompt.calledWith(
|
||||
PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR));
|
||||
});
|
||||
|
||||
it('onInputKeyUp calls showPasswordPrompt with the right password field', function () {
|
||||
var event = new $.Event('keyup');
|
||||
event.currentTarget = PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR;
|
||||
view.onInputKeyUp(event);
|
||||
assert.isTrue(view.showPasswordPrompt.calledWith(
|
||||
PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR));
|
||||
});
|
||||
});
|
||||
|
||||
describe('checks password strength and displays tooltip if required', function () {
|
||||
beforeEach(function () {
|
||||
view = new TestView(viewOpts);
|
||||
return view.render();
|
||||
});
|
||||
|
||||
it('calls checkPasswordStrength with the right password', function () {
|
||||
var password = 'charlie2';
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).val(password);
|
||||
sinon.stub(view, 'checkPasswordStrength', function (password) {
|
||||
// do nothing
|
||||
});
|
||||
view.onPasswordBlur();
|
||||
assert.isTrue(view.checkPasswordStrength.calledWith('charlie2'));
|
||||
});
|
||||
|
||||
it('displays tooltip when password is weak', function () {
|
||||
var password = 'charlie2';
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).val(password);
|
||||
sinon.stub(view, 'checkPasswordStrength', function (password) {
|
||||
view.displayPasswordWarningPrompt();
|
||||
});
|
||||
view.lang = 'en-rr';
|
||||
view.onPasswordBlur();
|
||||
return p()
|
||||
// wait for tooltip
|
||||
.delay(50)
|
||||
.then(() => {
|
||||
assert.equal(view.$(TOOLTIP_SELECTOR).length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not display tooltip when password is strong', function () {
|
||||
var password = 'imstronglol';
|
||||
view.$(PasswordPromptMixin.CHECK_PASSWORD_FIELD_SELECTOR).val(password);
|
||||
sinon.stub(view, 'checkPasswordStrength', function (password) {
|
||||
// do nothing
|
||||
});
|
||||
view.onPasswordBlur();
|
||||
return p()
|
||||
// wait for tooltip
|
||||
.delay(50)
|
||||
.then(() => {
|
||||
assert.equal(view.$(TOOLTIP_SELECTOR).length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,149 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
const BaseView = require('views/base');
|
||||
const chai = require('chai');
|
||||
const Cocktail = require('cocktail');
|
||||
const PasswordStrengthMixin = require('views/mixins/password-strength-mixin');
|
||||
const sinon = require('sinon');
|
||||
|
||||
var assert = chai.assert;
|
||||
|
||||
describe('views/mixins/password-strength-mixin', function () {
|
||||
// has a dot at the end
|
||||
var EVENT_NAME_PREFIX = 'experiment.pw_strength.';
|
||||
var view;
|
||||
var View = BaseView.extend({
|
||||
// nothing to extend
|
||||
});
|
||||
|
||||
Cocktail.mixin(
|
||||
View,
|
||||
PasswordStrengthMixin
|
||||
);
|
||||
|
||||
describe('isPasswordStrengthCheckEnabled', function () {
|
||||
it('calls able to make the choice', function () {
|
||||
var ableMock = {
|
||||
choose: sinon.spy(function () {
|
||||
return true;
|
||||
})
|
||||
};
|
||||
|
||||
view = new View({
|
||||
able: ableMock,
|
||||
metrics: {
|
||||
isCollectionEnabled () {
|
||||
return true;
|
||||
},
|
||||
logViewEvent: sinon.spy()
|
||||
},
|
||||
user: {
|
||||
get () {
|
||||
return 'userid';
|
||||
}
|
||||
},
|
||||
window: {
|
||||
location: {
|
||||
search: '?passwordStrengthCheck=true'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sinon.spy(view, 'logViewEvent');
|
||||
assert.isTrue(view.isPasswordStrengthCheckEnabled());
|
||||
assert.isTrue(
|
||||
ableMock.choose.calledWith('passwordStrengthCheckEnabled', {
|
||||
forcePasswordStrengthCheck: 'true',
|
||||
isMetricsEnabledValue: true,
|
||||
uniqueUserId: 'userid'
|
||||
})
|
||||
);
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'enabled'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('disabled', function () {
|
||||
it('does not attempt to check password', function () {
|
||||
view = new View();
|
||||
sinon.spy(view, 'logViewEvent');
|
||||
|
||||
sinon.stub(view, 'isPasswordStrengthCheckEnabled', function () {
|
||||
return false;
|
||||
});
|
||||
|
||||
sinon.spy(view, 'getPasswordStrengthChecker');
|
||||
return view.checkPasswordStrength('password')
|
||||
.then(function (status) {
|
||||
assert.equal(status, 'DISABLED');
|
||||
assert.isFalse(view.getPasswordStrengthChecker.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('enabled', function () {
|
||||
beforeEach(function () {
|
||||
view = new View();
|
||||
sinon.spy(view, 'logViewEvent');
|
||||
sinon.stub(view, 'isPasswordStrengthCheckEnabled', function () {
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `too_short` when password is short', function () {
|
||||
return view.checkPasswordStrength('hello')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'too_short'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `missing_password` when no password is passed', function () {
|
||||
return view.checkPasswordStrength('')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'missing_password'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `all_letters_or_numbers` when password is all numbers', function () {
|
||||
return view.checkPasswordStrength('123456789')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'all_letters_or_numbers'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `all_letters_or_numbers` when password is all letters', function () {
|
||||
return view.checkPasswordStrength('dragondrag')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'all_letters_or_numbers'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `long_enough` when password is >= 12 chars', function () {
|
||||
return view.checkPasswordStrength('imsuperlongandstrong')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'long_enough'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `bloomfilter_used` and `bloomfilter_hit` when password is in Bloom filter', function () {
|
||||
return view.checkPasswordStrength('charlie2')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'bloomfilter_used'));
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'bloomfilter_hit'));
|
||||
});
|
||||
});
|
||||
|
||||
it('logs `bloomfilter_used` and `bloomfilter_miss` when checked against Bloom filter but not present', function () {
|
||||
return view.checkPasswordStrength('pO09kskAs')
|
||||
.then(function () {
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'bloomfilter_used'));
|
||||
assert.isTrue(view.logViewEvent.calledWith(EVENT_NAME_PREFIX + 'bloomfilter_miss'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -372,24 +372,6 @@ define(function (require, exports, module) {
|
|||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('loads the password strength checker if enabled', function () {
|
||||
sinon.stub(view, 'isPasswordStrengthCheckEnabled', function () {
|
||||
return true;
|
||||
});
|
||||
|
||||
sinon.stub(view, 'getPasswordStrengthChecker', function () {
|
||||
return true;
|
||||
});
|
||||
|
||||
return view.render()
|
||||
.then(function () {
|
||||
return view.afterVisible();
|
||||
})
|
||||
.then(function () {
|
||||
assert.isTrue(view.getPasswordStrengthChecker.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValid', function () {
|
||||
|
@ -1238,19 +1220,6 @@ define(function (require, exports, module) {
|
|||
});
|
||||
});
|
||||
|
||||
describe('onPasswordBlur', function () {
|
||||
beforeEach(function () {
|
||||
sinon.spy(view, 'checkPasswordStrength');
|
||||
});
|
||||
|
||||
it('calls checkPasswordStrength with provided password', function () {
|
||||
var password = 'somerandomvalue';
|
||||
view.$('.password').val(password);
|
||||
view.onPasswordBlur();
|
||||
assert.isTrue(view.checkPasswordStrength.calledWith(password));
|
||||
});
|
||||
});
|
||||
|
||||
describe('onAmoSignIn', function () {
|
||||
beforeEach(function () {
|
||||
relier.set('email', email);
|
||||
|
|
|
@ -139,9 +139,7 @@ function (Translator, Session) {
|
|||
'../tests/spec/views/mixins/modal-settings-panel-mixin',
|
||||
'../tests/spec/views/mixins/open-webmail-mixin',
|
||||
'../tests/spec/views/mixins/password-mixin',
|
||||
'../tests/spec/views/mixins/password-prompt-mixin',
|
||||
'../tests/spec/views/mixins/password-reset-mixin',
|
||||
'../tests/spec/views/mixins/password-strength-mixin',
|
||||
'../tests/spec/views/mixins/pulse-graphic-mixin',
|
||||
'../tests/spec/views/mixins/resend-mixin',
|
||||
'../tests/spec/views/mixins/resume-token-mixin',
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
"easteregg": "https://github.com/mozilla/fxa-easter-egg.git#ab20cd517cf8ae9feee115e48745189d28e13bc3",
|
||||
"fxa-checkbox": "mozilla/fxa-checkbox#7f856afffd394a144f718e28e6fb79092d6ccddd",
|
||||
"fxa-js-client": "https://github.com/mozilla/fxa-js-client.git#0.1.54",
|
||||
"fxa-password-strength-checker": "https://github.com/mozilla/fxa-password-strength-checker.git#d73b3ade374607e2749ee375301b0a168008b16f",
|
||||
"html5shiv": "3.7.2",
|
||||
"JavaScript-MD5": "1.1.0",
|
||||
"jquery": "3.1.0",
|
||||
|
|
Загрузка…
Ссылка в новой задаче