LT-97: Password validation
LT-107: Login session timeout after 30 min
This commit is contained in:
parent
59a6905eb0
commit
d3671a5bdd
@ -19,7 +19,7 @@ check@1.1.0
|
||||
clinical:active-entry@1.5.14
|
||||
clinical:auto-resizing@0.1.2
|
||||
clinical:error-pages@0.1.1
|
||||
clinical:extended-api@2.2.1
|
||||
clinical:extended-api@2.2.2
|
||||
clinical:fonts@1.0.0
|
||||
clinical:hipaa-audit-log@2.4.2
|
||||
clinical:hipaa-logger@1.0.1
|
||||
@ -27,7 +27,8 @@ clinical:router@2.0.17
|
||||
clinical:router-location@2.0.14
|
||||
clinical:router-middleware-stack@2.0.13
|
||||
clinical:router-url@2.0.15
|
||||
clinical:theming@0.3.1
|
||||
clinical:theming@0.4.7
|
||||
codetheweb:zxcvbn@4.0.1
|
||||
coffeescript@1.0.11
|
||||
cornerstone@0.0.1
|
||||
ddp@1.2.2
|
||||
@ -44,7 +45,7 @@ ejson@1.0.7
|
||||
email@1.0.8
|
||||
es5-shim@4.1.14
|
||||
fastclick@1.0.7
|
||||
fortawesome:fontawesome@4.4.0
|
||||
fortawesome:fontawesome@4.5.0
|
||||
geojson-utils@1.0.4
|
||||
grove:less@0.1.1
|
||||
hangingprotocols@0.0.1
|
||||
@ -52,7 +53,7 @@ hot-code-push@1.0.0
|
||||
html-tools@1.0.5
|
||||
htmljs@1.0.5
|
||||
http@1.1.1
|
||||
ian:accounts-ui-bootstrap-3@1.2.83
|
||||
ian:accounts-ui-bootstrap-3@1.2.89
|
||||
id-map@1.0.4
|
||||
insecure@1.0.4
|
||||
iron:controller@1.0.12
|
||||
@ -72,7 +73,7 @@ minifiers@1.1.7
|
||||
minimongo@1.0.10
|
||||
mobile-experience@1.0.1
|
||||
mobile-status-bar@1.0.6
|
||||
momentjs:moment@2.10.6
|
||||
momentjs:moment@2.11.1
|
||||
mongo@1.1.3
|
||||
mongo-id@1.0.1
|
||||
mrt:moment@2.8.1
|
||||
@ -80,8 +81,8 @@ npm-bcrypt@0.7.8_2
|
||||
npm-mongo@1.4.39_1
|
||||
observe-sequence@1.0.7
|
||||
ordered-dict@1.0.4
|
||||
practicalmeteor:chai@1.9.2_3
|
||||
practicalmeteor:loglevel@1.1.0_3
|
||||
practicalmeteor:chai@2.1.0_1
|
||||
practicalmeteor:loglevel@1.2.0_2
|
||||
promise@0.5.1
|
||||
random@1.0.5
|
||||
rate-limit@1.0.0
|
||||
@ -102,7 +103,7 @@ stylus@2.511.1
|
||||
templating@1.1.5
|
||||
templating-tools@1.0.0
|
||||
tracker@1.0.9
|
||||
twbs:bootstrap@3.3.5
|
||||
twbs:bootstrap@3.3.6
|
||||
ui@1.0.8
|
||||
underscore@1.0.4
|
||||
url@1.0.5
|
||||
@ -110,3 +111,4 @@ viewerbase@0.0.1
|
||||
webapp@1.2.3
|
||||
webapp-hashing@1.0.5
|
||||
worklist@0.0.1
|
||||
zuuk:stale-session@1.0.8
|
||||
|
||||
@ -57,7 +57,7 @@ Template.entrySignIn.helpers({
|
||||
getPasswordValidationStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('password', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is weak")) {
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is invalid")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password present")) {
|
||||
return "border: 1px solid green";
|
||||
|
||||
@ -11,12 +11,20 @@
|
||||
<div id="signUpPageMessage" class="subtitle-auth" style="{{getSignUpMessageColor}}">{{getSignUpMessage}}</div>
|
||||
|
||||
<form>
|
||||
{{#if errorMessages}}
|
||||
<!--{{#if errorMessages}}
|
||||
<div id="errorMessages" class="list-errors">
|
||||
{{#each errorMessages}}
|
||||
<div class="alert alert-danger list-item">{{this}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}-->
|
||||
|
||||
{{#if entryErrorMessages}}
|
||||
<div id="errorMessages" class="list-errors">
|
||||
{{#each entryErrorMessages}}
|
||||
<div class="alert alert-danger list-item">{{this}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="input-symbol ">
|
||||
|
||||
@ -29,6 +29,20 @@ Template.entrySignUp.helpers({
|
||||
return Session.get('defaultSignInMessage');
|
||||
}
|
||||
},
|
||||
|
||||
entryErrorMessages: function () {
|
||||
var errorMessages = [];
|
||||
Object.keys(ActiveEntry.errorMessages.all()).forEach(function(key) {
|
||||
if (key !== "signInError" && ActiveEntry.errorMessages.get(key) &&
|
||||
ActiveEntry.errorMessages.get(key) !== "null" &&
|
||||
ActiveEntry.errorMessages.get(key) !== undefined &&
|
||||
ActiveEntry.errorMessages.get(key) !== null) {
|
||||
errorMessages.push(ActiveEntry.errorMessages.get(key));
|
||||
}
|
||||
});
|
||||
return errorMessages;
|
||||
},
|
||||
|
||||
getButtonText: function () {
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return ActiveEntry.errorMessages.get('signInError').message;
|
||||
@ -41,7 +55,7 @@ Template.entrySignUp.helpers({
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email is poorly formatted")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email present")) {
|
||||
} else if (ActiveEntry.successMessages.equals('email', "Email present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
@ -50,9 +64,9 @@ Template.entrySignUp.helpers({
|
||||
getPasswordStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('password', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is weak")) {
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is invalid")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password present")) {
|
||||
} else if (ActiveEntry.successMessages.equals('password', "Password present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
@ -61,9 +75,9 @@ Template.entrySignUp.helpers({
|
||||
getConfirmPasswordStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('confirm', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('confirm', "Password is weak")) {
|
||||
} else if (ActiveEntry.errorMessages.equals('confirm', "Password is invalid")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('confirm', "Passwords match")) {
|
||||
} else if (ActiveEntry.successMessages.equals('confirm', "Passwords match")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
@ -74,7 +88,7 @@ Template.entrySignUp.helpers({
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('fullName', "Name is probably not complete")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('fullName', "Name present")) {
|
||||
} else if (ActiveEntry.successMessages.equals('fullName', "Name present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
@ -120,7 +134,7 @@ Template.entrySignUp.events({
|
||||
event.preventDefault();
|
||||
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
ActiveEntry.verifyPassword(event, template);
|
||||
//ActiveEntry.verifyPassword(event, template);
|
||||
|
||||
var newUser = {
|
||||
fullName: template.$('[name="fullName"]').val(),
|
||||
@ -137,3 +151,8 @@ Template.entrySignUp.events({
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Template.entrySignUp.onRendered(function() {
|
||||
// Password strength meter for password inputs
|
||||
this.$(':password').pwstrength(pwstrengthOptions);
|
||||
});
|
||||
|
||||
@ -5,3 +5,7 @@
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
@ -31,6 +31,9 @@ if (Meteor.isClient) {
|
||||
ActiveEntry.errorMessages = new ReactiveDict('errorMessages');
|
||||
ActiveEntry.errorMessages.set('signInError', false);
|
||||
|
||||
// Success messages
|
||||
ActiveEntry.successMessages = new ReactiveDict('successMessages');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -46,39 +49,48 @@ ActiveEntry.configure = function (configObject) {
|
||||
ActiveEntry.verifyPassword = function (password) {
|
||||
if (password.length === 0) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password is required');
|
||||
} else if (password.length < 8) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password is weak');
|
||||
} else if (password.length >= 8) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password present');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyConfirmPassword = function (password, confirmPassword) {
|
||||
if (confirmPassword.length === 0) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Password is required');
|
||||
} else if (confirmPassword.length < 8) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Password is weak');
|
||||
ActiveEntry.successMessages.set('password', null);
|
||||
} else if (!validatePassword(password)) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password is invalid');
|
||||
ActiveEntry.successMessages.set('password', null);
|
||||
} else {
|
||||
//ActiveEntry.errorMessages.set('password', 'Password present');
|
||||
ActiveEntry.errorMessages.set('password', null);
|
||||
ActiveEntry.successMessages.set('password', 'Password present');
|
||||
}
|
||||
|
||||
};
|
||||
ActiveEntry.verifyConfirmPassword = function (password, confirmPassword) {
|
||||
if (confirmPassword === password) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Passwords match');
|
||||
//ActiveEntry.errorMessages.set('confirm', 'Passwords match');
|
||||
ActiveEntry.errorMessages.set('confirm', null);
|
||||
ActiveEntry.successMessages.set('confirm', 'Passwords match');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyEmail = function (email) {
|
||||
if (email.length === 0) {
|
||||
ActiveEntry.errorMessages.set('email', 'Email is required');
|
||||
ActiveEntry.successMessages.set('email', null);
|
||||
} else if (email.indexOf("@") === -1){
|
||||
ActiveEntry.errorMessages.set('email', 'Email is poorly formatted');
|
||||
ActiveEntry.successMessages.set('email', null);
|
||||
} else if (email.indexOf("@") >= 0){
|
||||
ActiveEntry.errorMessages.set('email', 'Email present');
|
||||
//ActiveEntry.errorMessages.set('email', 'Email present');
|
||||
ActiveEntry.errorMessages.set('email', null);
|
||||
ActiveEntry.successMessages.set('email', 'Email present');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyFullName = function (fullName) {
|
||||
if (fullName.length === 0) {
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name is required');
|
||||
ActiveEntry.successMessages.set('fullName', null);
|
||||
} else if (fullName.indexOf(" ") === -1){
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name is probably not complete');
|
||||
ActiveEntry.successMessages.set('fullName', null);
|
||||
} else if (fullName.indexOf(" ") >= 0){
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name present');
|
||||
//ActiveEntry.errorMessages.set('fullName', 'Name present');
|
||||
ActiveEntry.errorMessages.set('fullName', null);
|
||||
ActiveEntry.successMessages.set('fullName', 'Name present');
|
||||
}
|
||||
};
|
||||
|
||||
@ -104,6 +116,18 @@ ActiveEntry.signUp = function (emailValue, passwordValue, confirmPassword, fullN
|
||||
ActiveEntry.verifyConfirmPassword(passwordValue, confirmPassword);
|
||||
ActiveEntry.verifyFullName(fullName);
|
||||
|
||||
var errorIsFound = false;
|
||||
Object.keys(ActiveEntry.errorMessages.keys).forEach(function(key) {
|
||||
if (ActiveEntry.errorMessages.get(key) !== "null" && ActiveEntry.errorMessages.get(key) !== null) {
|
||||
errorIsFound = true;
|
||||
}
|
||||
});
|
||||
|
||||
if(errorIsFound) {
|
||||
// TODO: Show error messages
|
||||
return;
|
||||
}
|
||||
|
||||
Accounts.createUser({
|
||||
email: emailValue,
|
||||
password: passwordValue,
|
||||
|
||||
708
Packages/active-entry/lib/jquery.pwstrength.bootstrap.js
Normal file
708
Packages/active-entry/lib/jquery.pwstrength.bootstrap.js
Normal file
@ -0,0 +1,708 @@
|
||||
/*!
|
||||
* jQuery Password Strength plugin for Twitter Bootstrap
|
||||
*
|
||||
* Copyright (c) 2008-2013 Tane Piper
|
||||
* Copyright (c) 2013 Alejandro Blanco
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
*/
|
||||
|
||||
(function (jQuery) {
|
||||
// Source: src/rules.js
|
||||
|
||||
|
||||
|
||||
|
||||
var rulesEngine = {};
|
||||
|
||||
try {
|
||||
if (!jQuery && module && module.exports) {
|
||||
var jQuery = require("jquery"),
|
||||
jsdom = require("jsdom").jsdom;
|
||||
jQuery = jQuery(jsdom().parentWindow);
|
||||
}
|
||||
} catch (ignore) {}
|
||||
|
||||
(function ($, rulesEngine) {
|
||||
"use strict";
|
||||
var validation = {};
|
||||
|
||||
rulesEngine.forbiddenSequences = [
|
||||
"0123456789", "abcdefghijklmnopqrstuvwxyz", "qwertyuiop", "asdfghjkl",
|
||||
"zxcvbnm", "!@#$%^&*()_+"
|
||||
];
|
||||
|
||||
validation.wordNotEmail = function (options, word, score) {
|
||||
if (word.match(/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i)) {
|
||||
return score;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
validation.wordLength = function (options, word, score) {
|
||||
var wordlen = word.length,
|
||||
lenScore = Math.pow(wordlen, options.rules.raisePower);
|
||||
if (wordlen < options.common.minChar) {
|
||||
lenScore = (lenScore + score);
|
||||
}
|
||||
return lenScore;
|
||||
};
|
||||
|
||||
validation.wordSimilarToUsername = function (options, word, score) {
|
||||
var username = $(options.common.usernameField).val();
|
||||
if (username && word.toLowerCase().match(username.replace(/[\-\[\]\/\{\}\(\)\*\+\=\?\:\.\\\^\$\|\!\,]/g, "\\$&").toLowerCase())) {
|
||||
return score;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
validation.wordTwoCharacterClasses = function (options, word, score) {
|
||||
if (word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) ||
|
||||
(word.match(/([a-zA-Z])/) && word.match(/([0-9])/)) ||
|
||||
(word.match(/(.[!,@,#,$,%,\^,&,*,?,_,~])/) && word.match(/[a-zA-Z0-9_]/))) {
|
||||
return score;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
validation.wordRepetitions = function (options, word, score) {
|
||||
if (word.match(/(.)\1\1/)) { return score; }
|
||||
return 0;
|
||||
};
|
||||
|
||||
validation.wordSequences = function (options, word, score) {
|
||||
var found = false,
|
||||
j;
|
||||
if (word.length > 2) {
|
||||
$.each(rulesEngine.forbiddenSequences, function (idx, seq) {
|
||||
if (found) { return; }
|
||||
var sequences = [seq, seq.split('').reverse().join('')];
|
||||
$.each(sequences, function (idx, sequence) {
|
||||
for (j = 0; j < (word.length - 2); j += 1) { // iterate the word trough a sliding window of size 3:
|
||||
if (sequence.indexOf(word.toLowerCase().substring(j, j + 3)) > -1) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
if (found) { return score; }
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
validation.wordLowercase = function (options, word, score) {
|
||||
return word.match(/[a-z]/) && score;
|
||||
};
|
||||
|
||||
validation.wordUppercase = function (options, word, score) {
|
||||
return word.match(/[A-Z]/) && score;
|
||||
};
|
||||
|
||||
validation.wordOneNumber = function (options, word, score) {
|
||||
return word.match(/\d+/) && score;
|
||||
};
|
||||
|
||||
validation.wordThreeNumbers = function (options, word, score) {
|
||||
return word.match(/(.*[0-9].*[0-9].*[0-9])/) && score;
|
||||
};
|
||||
|
||||
validation.wordOneSpecialChar = function (options, word, score) {
|
||||
return word.match(/[!,@,#,$,%,\^,&,*,?,_,~]/) && score;
|
||||
};
|
||||
|
||||
validation.wordTwoSpecialChar = function (options, word, score) {
|
||||
return word.match(/(.*[!,@,#,$,%,\^,&,*,?,_,~].*[!,@,#,$,%,\^,&,*,?,_,~])/) && score;
|
||||
};
|
||||
|
||||
validation.wordUpperLowerCombo = function (options, word, score) {
|
||||
return word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && score;
|
||||
};
|
||||
|
||||
validation.wordLetterNumberCombo = function (options, word, score) {
|
||||
return word.match(/([a-zA-Z])/) && word.match(/([0-9])/) && score;
|
||||
};
|
||||
|
||||
validation.wordLetterNumberCharCombo = function (options, word, score) {
|
||||
return word.match(/([a-zA-Z0-9].*[!,@,#,$,%,\^,&,*,?,_,~])|([!,@,#,$,%,\^,&,*,?,_,~].*[a-zA-Z0-9])/) && score;
|
||||
};
|
||||
|
||||
rulesEngine.validation = validation;
|
||||
|
||||
rulesEngine.executeRules = function (options, word) {
|
||||
var totalScore = 0;
|
||||
|
||||
$.each(options.rules.activated, function (rule, active) {
|
||||
if (active) {
|
||||
var score = options.rules.scores[rule],
|
||||
funct = rulesEngine.validation[rule],
|
||||
result,
|
||||
errorMessage;
|
||||
|
||||
if (!$.isFunction(funct)) {
|
||||
funct = options.rules.extra[rule];
|
||||
}
|
||||
|
||||
if ($.isFunction(funct)) {
|
||||
result = funct(options, word, score);
|
||||
if (result) {
|
||||
totalScore += result;
|
||||
}
|
||||
if (result < 0 || (!$.isNumeric(result) && !result)) {
|
||||
errorMessage = options.ui.spanError(options, rule);
|
||||
if (errorMessage.length > 0) {
|
||||
options.instances.errors.push(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return totalScore;
|
||||
};
|
||||
}(jQuery, rulesEngine));
|
||||
|
||||
try {
|
||||
if (module && module.exports) {
|
||||
module.exports = rulesEngine;
|
||||
}
|
||||
} catch (ignore) {}
|
||||
|
||||
// Source: src/options.js
|
||||
|
||||
|
||||
|
||||
|
||||
var defaultOptions = {};
|
||||
|
||||
defaultOptions.common = {};
|
||||
defaultOptions.common.minChar = 6;
|
||||
defaultOptions.common.usernameField = "#username";
|
||||
defaultOptions.common.userInputs = [
|
||||
// Selectors for input fields with user input
|
||||
];
|
||||
defaultOptions.common.onLoad = undefined;
|
||||
defaultOptions.common.onKeyUp = undefined;
|
||||
defaultOptions.common.zxcvbn = false;
|
||||
defaultOptions.common.zxcvbnTerms = [
|
||||
// List of disrecommended words
|
||||
];
|
||||
defaultOptions.common.debug = false;
|
||||
|
||||
defaultOptions.rules = {};
|
||||
defaultOptions.rules.extra = {};
|
||||
defaultOptions.rules.scores = {
|
||||
wordNotEmail: -100,
|
||||
wordLength: -50,
|
||||
wordSimilarToUsername: -100,
|
||||
wordSequences: -20,
|
||||
wordTwoCharacterClasses: 2,
|
||||
wordRepetitions: -25,
|
||||
wordLowercase: 1,
|
||||
wordUppercase: 3,
|
||||
wordOneNumber: 3,
|
||||
wordThreeNumbers: 5,
|
||||
wordOneSpecialChar: 3,
|
||||
wordTwoSpecialChar: 5,
|
||||
wordUpperLowerCombo: 2,
|
||||
wordLetterNumberCombo: 2,
|
||||
wordLetterNumberCharCombo: 2
|
||||
};
|
||||
defaultOptions.rules.activated = {
|
||||
wordNotEmail: true,
|
||||
wordLength: true,
|
||||
wordSimilarToUsername: true,
|
||||
wordSequences: true,
|
||||
wordTwoCharacterClasses: false,
|
||||
wordRepetitions: false,
|
||||
wordLowercase: true,
|
||||
wordUppercase: true,
|
||||
wordOneNumber: true,
|
||||
wordThreeNumbers: true,
|
||||
wordOneSpecialChar: true,
|
||||
wordTwoSpecialChar: true,
|
||||
wordUpperLowerCombo: true,
|
||||
wordLetterNumberCombo: true,
|
||||
wordLetterNumberCharCombo: true
|
||||
};
|
||||
defaultOptions.rules.raisePower = 1.4;
|
||||
|
||||
defaultOptions.ui = {};
|
||||
defaultOptions.ui.bootstrap2 = false;
|
||||
defaultOptions.ui.bootstrap4 = false;
|
||||
defaultOptions.ui.colorClasses = ["danger", "warning", "success"];
|
||||
defaultOptions.ui.showProgressBar = true;
|
||||
defaultOptions.ui.showPopover = false;
|
||||
defaultOptions.ui.popoverPlacement = "bottom";
|
||||
defaultOptions.ui.showStatus = false;
|
||||
defaultOptions.ui.spanError = function (options, key) {
|
||||
"use strict";
|
||||
var text = options.ui.errorMessages[key];
|
||||
if (!text) { return ''; }
|
||||
return '<span style="color: #d52929">' + text + '</span>';
|
||||
};
|
||||
defaultOptions.ui.popoverError = function (errors) {
|
||||
"use strict";
|
||||
var message = "<div>Errors:<ul class='error-list' style='margin-bottom: 0;'>";
|
||||
|
||||
jQuery.each(errors, function (idx, err) {
|
||||
message += "<li>" + err + "</li>";
|
||||
});
|
||||
message += "</ul></div>";
|
||||
return message;
|
||||
};
|
||||
defaultOptions.ui.errorMessages = {
|
||||
wordLength: "Your password is too short",
|
||||
wordNotEmail: "Do not use your email as your password",
|
||||
wordSimilarToUsername: "Your password cannot contain your username",
|
||||
wordTwoCharacterClasses: "Use different character classes",
|
||||
wordRepetitions: "Too many repetitions",
|
||||
wordSequences: "Your password contains sequences"
|
||||
};
|
||||
defaultOptions.ui.verdicts = ["Weak", "Normal", "Medium", "Strong", "Very Strong"];
|
||||
defaultOptions.ui.showVerdicts = true;
|
||||
defaultOptions.ui.showVerdictsInsideProgressBar = false;
|
||||
defaultOptions.ui.useVerdictCssClass = false;
|
||||
defaultOptions.ui.showErrors = false;
|
||||
defaultOptions.ui.container = undefined;
|
||||
defaultOptions.ui.viewports = {
|
||||
progress: undefined,
|
||||
verdict: undefined,
|
||||
errors: undefined
|
||||
};
|
||||
defaultOptions.ui.scores = [14, 26, 38, 50];
|
||||
|
||||
// Source: src/ui.js
|
||||
|
||||
|
||||
|
||||
|
||||
var ui = {};
|
||||
|
||||
(function ($, ui) {
|
||||
"use strict";
|
||||
|
||||
var statusClasses = ["error", "warning", "success"];
|
||||
|
||||
ui.getContainer = function (options, $el) {
|
||||
var $container;
|
||||
|
||||
$container = $(options.ui.container);
|
||||
if (!($container && $container.length === 1)) {
|
||||
$container = $el.parent();
|
||||
}
|
||||
return $container;
|
||||
};
|
||||
|
||||
ui.findElement = function ($container, viewport, cssSelector) {
|
||||
if (viewport) {
|
||||
return $container.find(viewport).find(cssSelector);
|
||||
}
|
||||
return $container.find(cssSelector);
|
||||
};
|
||||
|
||||
ui.getUIElements = function (options, $el) {
|
||||
var $container, selector, result;
|
||||
|
||||
if (options.instances.viewports) {
|
||||
return options.instances.viewports;
|
||||
}
|
||||
|
||||
$container = ui.getContainer(options, $el);
|
||||
|
||||
result = {};
|
||||
if (options.ui.bootstrap4) {
|
||||
selector = "progress.progress";
|
||||
} else {
|
||||
selector = "div.progress";
|
||||
}
|
||||
result.$progressbar = ui.findElement($container, options.ui.viewports.progress, selector);
|
||||
if (options.ui.showVerdictsInsideProgressBar) {
|
||||
result.$verdict = result.$progressbar.find("span.password-verdict");
|
||||
}
|
||||
|
||||
if (!options.ui.showPopover) {
|
||||
if (!options.ui.showVerdictsInsideProgressBar) {
|
||||
result.$verdict = ui.findElement($container, options.ui.viewports.verdict, "span.password-verdict");
|
||||
}
|
||||
result.$errors = ui.findElement($container, options.ui.viewports.errors, "ul.error-list");
|
||||
}
|
||||
|
||||
options.instances.viewports = result;
|
||||
return result;
|
||||
};
|
||||
|
||||
ui.initProgressBar = function (options, $el) {
|
||||
var $container = ui.getContainer(options, $el),
|
||||
progressbar = "<div class='progress'><div class='"; // Boostrap 2
|
||||
|
||||
if (!options.ui.bootstrap2 && !options.ui.bootstrap4) {
|
||||
// Bootstrap 3
|
||||
progressbar += "progress-";
|
||||
}
|
||||
progressbar += "bar'>";
|
||||
if (options.ui.bootstrap4) {
|
||||
// Boostrap 4
|
||||
progressbar = "<progress class='progress' value='0' max='100'>";
|
||||
}
|
||||
if (options.ui.showVerdictsInsideProgressBar) {
|
||||
progressbar += "<span class='password-verdict'></span>";
|
||||
}
|
||||
if (options.ui.bootstrap4) {
|
||||
progressbar += "</progress>";
|
||||
} else {
|
||||
progressbar += "</div></div>";
|
||||
}
|
||||
|
||||
if (options.ui.viewports.progress) {
|
||||
$container.find(options.ui.viewports.progress).append(progressbar);
|
||||
} else {
|
||||
$(progressbar).insertAfter($el);
|
||||
}
|
||||
};
|
||||
|
||||
ui.initHelper = function (options, $el, html, viewport) {
|
||||
var $container = ui.getContainer(options, $el);
|
||||
if (viewport) {
|
||||
$container.find(viewport).append(html);
|
||||
} else {
|
||||
$(html).insertAfter($el);
|
||||
}
|
||||
};
|
||||
|
||||
ui.initVerdict = function (options, $el) {
|
||||
ui.initHelper(options, $el, "<span class='password-verdict'></span>",
|
||||
options.ui.viewports.verdict);
|
||||
};
|
||||
|
||||
ui.initErrorList = function (options, $el) {
|
||||
ui.initHelper(options, $el, "<ul class='error-list'></ul>",
|
||||
options.ui.viewports.errors);
|
||||
};
|
||||
|
||||
ui.initPopover = function (options, $el) {
|
||||
$el.popover("destroy");
|
||||
$el.popover({
|
||||
html: true,
|
||||
placement: options.ui.popoverPlacement,
|
||||
trigger: "manual",
|
||||
content: " "
|
||||
});
|
||||
};
|
||||
|
||||
ui.initUI = function (options, $el) {
|
||||
if (options.ui.showPopover) {
|
||||
ui.initPopover(options, $el);
|
||||
} else {
|
||||
if (options.ui.showErrors) { ui.initErrorList(options, $el); }
|
||||
if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) {
|
||||
ui.initVerdict(options, $el);
|
||||
}
|
||||
}
|
||||
if (options.ui.showProgressBar) {
|
||||
ui.initProgressBar(options, $el);
|
||||
}
|
||||
};
|
||||
|
||||
ui.updateProgressBar = function (options, $el, cssClass, percentage) {
|
||||
var $progressbar = ui.getUIElements(options, $el).$progressbar,
|
||||
$bar = $progressbar.find(".progress-bar"),
|
||||
cssPrefix = "progress-";
|
||||
|
||||
if (options.ui.bootstrap2) {
|
||||
$bar = $progressbar.find(".bar");
|
||||
cssPrefix = "";
|
||||
}
|
||||
|
||||
$.each(options.ui.colorClasses, function (idx, value) {
|
||||
if (options.ui.bootstrap4) {
|
||||
$progressbar.removeClass(cssPrefix + value);
|
||||
} else {
|
||||
$bar.removeClass(cssPrefix + "bar-" + value);
|
||||
}
|
||||
});
|
||||
if (options.ui.bootstrap4) {
|
||||
$progressbar.addClass(cssPrefix + options.ui.colorClasses[cssClass]);
|
||||
$progressbar.val(percentage);
|
||||
} else {
|
||||
$bar.addClass(cssPrefix + "bar-" + options.ui.colorClasses[cssClass]);
|
||||
$bar.css("width", percentage + '%');
|
||||
}
|
||||
};
|
||||
|
||||
ui.updateVerdict = function (options, $el, cssClass, text) {
|
||||
var $verdict = ui.getUIElements(options, $el).$verdict;
|
||||
$verdict.removeClass(options.ui.colorClasses.join(' '));
|
||||
if (cssClass > -1) {
|
||||
$verdict.addClass(options.ui.colorClasses[cssClass]);
|
||||
}
|
||||
$verdict.html(text);
|
||||
};
|
||||
|
||||
ui.updateErrors = function (options, $el) {
|
||||
var $errors = ui.getUIElements(options, $el).$errors,
|
||||
html = "";
|
||||
$.each(options.instances.errors, function (idx, err) {
|
||||
html += "<li>" + err + "</li>";
|
||||
});
|
||||
$errors.html(html);
|
||||
};
|
||||
|
||||
ui.updatePopover = function (options, $el, verdictText) {
|
||||
var popover = $el.data("bs.popover"),
|
||||
html = "",
|
||||
hide = true;
|
||||
|
||||
if (options.ui.showVerdicts &&
|
||||
!options.ui.showVerdictsInsideProgressBar &&
|
||||
verdictText.length > 0) {
|
||||
html = "<h5><span class='password-verdict'>" + verdictText +
|
||||
"</span></h5>";
|
||||
hide = false;
|
||||
}
|
||||
if (options.ui.showErrors) {
|
||||
if (options.instances.errors.length > 0) {
|
||||
hide = false;
|
||||
}
|
||||
html += options.ui.popoverError(options.instances.errors);
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
$el.popover("hide");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.ui.bootstrap2) { popover = $el.data("popover"); }
|
||||
|
||||
if (popover.$arrow && popover.$arrow.parents("body").length > 0) {
|
||||
$el.find("+ .popover .popover-content").html(html);
|
||||
} else {
|
||||
// It's hidden
|
||||
popover.options.content = html;
|
||||
$el.popover("show");
|
||||
}
|
||||
};
|
||||
|
||||
ui.updateFieldStatus = function (options, $el, cssClass) {
|
||||
var targetClass = options.ui.bootstrap2 ? ".control-group" : ".form-group",
|
||||
$container = $el.parents(targetClass).first();
|
||||
|
||||
$.each(statusClasses, function (idx, css) {
|
||||
if (!options.ui.bootstrap2) { css = "has-" + css; }
|
||||
$container.removeClass(css);
|
||||
});
|
||||
|
||||
cssClass = statusClasses[cssClass];
|
||||
if (!options.ui.bootstrap2) { cssClass = "has-" + cssClass; }
|
||||
$container.addClass(cssClass);
|
||||
};
|
||||
|
||||
ui.percentage = function (score, maximun) {
|
||||
var result = Math.floor(100 * score / maximun);
|
||||
result = result <= 0 ? 1 : result; // Don't show the progress bar empty
|
||||
result = result > 100 ? 100 : result;
|
||||
return result;
|
||||
};
|
||||
|
||||
ui.getVerdictAndCssClass = function (options, score) {
|
||||
var cssClass, verdictText, level;
|
||||
|
||||
if (score <= 0) {
|
||||
cssClass = 0;
|
||||
level = -1;
|
||||
verdictText = options.ui.verdicts[0];
|
||||
} else if (score < options.ui.scores[0]) {
|
||||
cssClass = 0;
|
||||
level = 0;
|
||||
verdictText = options.ui.verdicts[0];
|
||||
} else if (score < options.ui.scores[1]) {
|
||||
cssClass = 0;
|
||||
level = 1;
|
||||
verdictText = options.ui.verdicts[1];
|
||||
} else if (score < options.ui.scores[2]) {
|
||||
cssClass = 1;
|
||||
level = 2;
|
||||
verdictText = options.ui.verdicts[2];
|
||||
} else if (score < options.ui.scores[3]) {
|
||||
cssClass = 1;
|
||||
level = 3;
|
||||
verdictText = options.ui.verdicts[3];
|
||||
} else {
|
||||
cssClass = 2;
|
||||
level = 4;
|
||||
verdictText = options.ui.verdicts[4];
|
||||
}
|
||||
|
||||
return [verdictText, cssClass, level];
|
||||
};
|
||||
|
||||
ui.updateUI = function (options, $el, score) {
|
||||
var cssClass, barPercentage, verdictText, verdictCssClass;
|
||||
|
||||
cssClass = ui.getVerdictAndCssClass(options, score);
|
||||
verdictText = score === 0 ? '' : cssClass[0];
|
||||
cssClass = cssClass[1];
|
||||
verdictCssClass = options.ui.useVerdictCssClass ? cssClass : -1;
|
||||
|
||||
if (options.ui.showProgressBar) {
|
||||
barPercentage = ui.percentage(score, options.ui.scores[3]);
|
||||
ui.updateProgressBar(options, $el, cssClass, barPercentage);
|
||||
if (options.ui.showVerdictsInsideProgressBar) {
|
||||
ui.updateVerdict(options, $el, verdictCssClass, verdictText);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.ui.showStatus) {
|
||||
ui.updateFieldStatus(options, $el, cssClass);
|
||||
}
|
||||
|
||||
if (options.ui.showPopover) {
|
||||
ui.updatePopover(options, $el, verdictText);
|
||||
} else {
|
||||
if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) {
|
||||
ui.updateVerdict(options, $el, verdictCssClass, verdictText);
|
||||
}
|
||||
if (options.ui.showErrors) {
|
||||
ui.updateErrors(options, $el);
|
||||
}
|
||||
}
|
||||
};
|
||||
}(jQuery, ui));
|
||||
|
||||
// Source: src/methods.js
|
||||
|
||||
|
||||
|
||||
|
||||
var methods = {};
|
||||
|
||||
(function ($, methods) {
|
||||
"use strict";
|
||||
var onKeyUp, applyToAll;
|
||||
|
||||
onKeyUp = function (event) {
|
||||
var $el = $(event.target),
|
||||
options = $el.data("pwstrength-bootstrap"),
|
||||
word = $el.val(),
|
||||
userInputs,
|
||||
verdictText,
|
||||
verdictLevel,
|
||||
score;
|
||||
|
||||
if (options === undefined) { return; }
|
||||
|
||||
options.instances.errors = [];
|
||||
if (word.length === 0) {
|
||||
score = 0;
|
||||
} else {
|
||||
if (options.common.zxcvbn) {
|
||||
userInputs = [];
|
||||
$.each(options.common.userInputs.concat([options.common.usernameField]), function (idx, selector) {
|
||||
var value = $(selector).val();
|
||||
if (value) { userInputs.push(value); }
|
||||
});
|
||||
userInputs = userInputs.concat(options.common.zxcvbnTerms);
|
||||
score = Math.log2(zxcvbn(word, userInputs).guesses);
|
||||
} else {
|
||||
score = rulesEngine.executeRules(options, word);
|
||||
}
|
||||
}
|
||||
ui.updateUI(options, $el, score);
|
||||
verdictText = ui.getVerdictAndCssClass(options, score);
|
||||
verdictLevel = verdictText[2];
|
||||
verdictText = verdictText[0];
|
||||
|
||||
if (options.common.debug) { console.log(score + ' - ' + verdictText); }
|
||||
|
||||
if ($.isFunction(options.common.onKeyUp)) {
|
||||
options.common.onKeyUp(event, {
|
||||
score: score,
|
||||
verdictText: verdictText,
|
||||
verdictLevel: verdictLevel
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
methods.init = function (settings) {
|
||||
this.each(function (idx, el) {
|
||||
// Make it deep extend (first param) so it extends too the
|
||||
// rules and other inside objects
|
||||
var clonedDefaults = $.extend(true, {}, defaultOptions),
|
||||
localOptions = $.extend(true, clonedDefaults, settings),
|
||||
$el = $(el);
|
||||
|
||||
localOptions.instances = {};
|
||||
$el.data("pwstrength-bootstrap", localOptions);
|
||||
$el.on("keyup", onKeyUp);
|
||||
$el.on("change", onKeyUp);
|
||||
$el.on("paste", onKeyUp);
|
||||
|
||||
ui.initUI(localOptions, $el);
|
||||
if ($.trim($el.val())) { // Not empty, calculate the strength
|
||||
$el.trigger("keyup");
|
||||
}
|
||||
|
||||
if ($.isFunction(localOptions.common.onLoad)) {
|
||||
localOptions.common.onLoad();
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
methods.destroy = function () {
|
||||
this.each(function (idx, el) {
|
||||
var $el = $(el),
|
||||
options = $el.data("pwstrength-bootstrap"),
|
||||
elements = ui.getUIElements(options, $el);
|
||||
elements.$progressbar.remove();
|
||||
elements.$verdict.remove();
|
||||
elements.$errors.remove();
|
||||
$el.removeData("pwstrength-bootstrap");
|
||||
});
|
||||
};
|
||||
|
||||
methods.forceUpdate = function () {
|
||||
this.each(function (idx, el) {
|
||||
var event = { target: el };
|
||||
onKeyUp(event);
|
||||
});
|
||||
};
|
||||
|
||||
methods.addRule = function (name, method, score, active) {
|
||||
this.each(function (idx, el) {
|
||||
var options = $(el).data("pwstrength-bootstrap");
|
||||
|
||||
options.rules.activated[name] = active;
|
||||
options.rules.scores[name] = score;
|
||||
options.rules.extra[name] = method;
|
||||
});
|
||||
};
|
||||
|
||||
applyToAll = function (rule, prop, value) {
|
||||
this.each(function (idx, el) {
|
||||
$(el).data("pwstrength-bootstrap").rules[prop][rule] = value;
|
||||
});
|
||||
};
|
||||
|
||||
methods.changeScore = function (rule, score) {
|
||||
applyToAll.call(this, rule, "scores", score);
|
||||
};
|
||||
|
||||
methods.ruleActive = function (rule, active) {
|
||||
applyToAll.call(this, rule, "activated", active);
|
||||
};
|
||||
|
||||
$.fn.pwstrength = function (method) {
|
||||
var result;
|
||||
|
||||
if (methods[method]) {
|
||||
result = methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === "object" || !method) {
|
||||
result = methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error("Method " + method + " does not exist on jQuery.pwstrength-bootstrap");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}(jQuery, methods));
|
||||
}(jQuery));
|
||||
19
Packages/active-entry/lib/validatePassword.js
Normal file
19
Packages/active-entry/lib/validatePassword.js
Normal file
@ -0,0 +1,19 @@
|
||||
pwstrengthOptions = {
|
||||
common: {
|
||||
minChar: 8,
|
||||
zxcvbn: true
|
||||
},
|
||||
ui: {
|
||||
showVerdictsInsideProgressBar: true,
|
||||
showStatus: true
|
||||
}
|
||||
};
|
||||
|
||||
// Validate Password: at least 8 characters in length and contain at least 1 uppercase, 1 lowercase and 1 number and 1 special character
|
||||
validatePassword = function(password) {
|
||||
var result = password.search(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])[0-9a-zA-Z!@#$%^&*]{8,}$/i);
|
||||
if (result > -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@ -17,7 +17,8 @@ Package.onUse(function (api) {
|
||||
'session',
|
||||
'reactive-dict',
|
||||
'accounts-base',
|
||||
'accounts-password'
|
||||
'accounts-password',
|
||||
'codetheweb:zxcvbn'
|
||||
], ['client']);
|
||||
|
||||
api.use([
|
||||
@ -25,11 +26,20 @@ Package.onUse(function (api) {
|
||||
'accounts-password'
|
||||
], ['server']);
|
||||
|
||||
api.use([
|
||||
'zuuk:stale-session@1.0.8'
|
||||
], ['client', 'server']);
|
||||
|
||||
api.addFiles([
|
||||
'lib/ActiveEntry.js',
|
||||
'lib/Accounts.js'
|
||||
]);
|
||||
|
||||
api.addFiles([
|
||||
'lib/jquery.pwstrength.bootstrap.js',
|
||||
'lib/validatePassword.js'
|
||||
], ['client']);
|
||||
|
||||
api.imply('accounts-base');
|
||||
api.imply('accounts-password');
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ describe('clinical:active-entry', function () {
|
||||
it('Email validation confirms it is a properly formatted email.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyEmail('janedoe@somewhere.com');
|
||||
expect(ActiveEntry.errorMessages.get('email')).to.equal("Email present");
|
||||
expect(ActiveEntry.successMessages.get('email')).to.equal("Email present");
|
||||
|
||||
ActiveEntry.verifyEmail('');
|
||||
expect(ActiveEntry.errorMessages.get('email')).to.equal("Email is required");
|
||||
@ -61,24 +61,18 @@ describe('clinical:active-entry', function () {
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password is required");
|
||||
|
||||
ActiveEntry.verifyPassword('kittens');
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password is weak");
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password is invalid");
|
||||
|
||||
ActiveEntry.verifyPassword('kittens123');
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password present");
|
||||
ActiveEntry.verifyPassword('K1tt#ns123');
|
||||
expect(ActiveEntry.successMessages.get('password')).to.equal("Password present");
|
||||
});
|
||||
});
|
||||
|
||||
// ActiveEntry.verifyConfirmPassword
|
||||
it('Password match validation confirms that two passwords are the same.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', '');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Password is required");
|
||||
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', 'kittens');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Password is weak");
|
||||
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', 'kittens123');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Passwords match");
|
||||
ActiveEntry.verifyConfirmPassword('K1tt#ns123', 'K1tt#ns123');
|
||||
expect(ActiveEntry.successMessages.get('confirm')).to.equal("Passwords match");
|
||||
});
|
||||
});
|
||||
|
||||
@ -92,7 +86,7 @@ describe('clinical:active-entry', function () {
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name is probably not complete");
|
||||
|
||||
ActiveEntry.verifyFullName('Jane Doe');
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name present");
|
||||
expect(ActiveEntry.successMessages.get('fullName')).to.equal("Name present");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ module.exports = {
|
||||
"user should be able to request be able to create new account" : function (client) {
|
||||
client.verify.elementPresent("#signUpPageEmailInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPagePasswordConfirmInput")
|
||||
.verify.elementPresent("#signUpPageJoinNowButton")
|
||||
},
|
||||
|
||||
@ -56,14 +56,14 @@ module.exports = {
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordInput", "jan")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid rgb(242, 222, 222)')
|
||||
.setValue("#signUpPagePasswordInput", "icedoe123")
|
||||
.setValue("#signUpPagePasswordInput", "iceD*e123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordConfirmInput", "ja")
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid rgb(242, 222, 222)')
|
||||
.clearValue("#signUpPagePasswordConfirmInput")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "Janiced*e123")
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid green')
|
||||
},
|
||||
"guest should be notified if passwords do not match" : function (client) {
|
||||
@ -74,10 +74,10 @@ module.exports = {
|
||||
.pause(500)
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid gray')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordInput", "Janiced*e123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "Janiced*e123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid green')
|
||||
},
|
||||
@ -104,8 +104,8 @@ module.exports = {
|
||||
|
||||
.setValue("#signUpPageFullNameInput", "Janice Doe")
|
||||
.setValue("#signUpPageEmailInput", "janicedoe@symptomatic.io")
|
||||
.setValue("#signUpPagePasswordInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordInput", "Janiced*e123")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "Janiced*e123")
|
||||
|
||||
.click("#signUpPageJoinNowButton").pause(1000)
|
||||
|
||||
@ -131,7 +131,7 @@ module.exports = {
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(1600, 1200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.signIn("janicedoe@symptomatic.io", "Janiced*e123").pause(500)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
@ -141,7 +141,7 @@ module.exports = {
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(1024, 768)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.signIn("janicedoe@symptomatic.io", "Janiced*e123").pause(500)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
@ -151,7 +151,7 @@ module.exports = {
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(320, 960)
|
||||
// .verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.signIn("janicedoe@symptomatic.io", "Janiced*e123").pause(500)
|
||||
.click("#sidebarToggle").pause(300)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
@ -171,7 +171,7 @@ module.exports = {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignUp")
|
||||
.resizeWindow(1024, 768)
|
||||
.signUp("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.signUp("janicedoe@symptomatic.io", "Janiced*e123").pause(500)
|
||||
.click("#signUpPageEmailInput").pause(500)
|
||||
.verify.elementPresent("#signUpPageMessage")
|
||||
.verify.containsText("#signUpPageMessage", "Email already exists. [403]")
|
||||
|
||||
@ -17,5 +17,11 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"public": {
|
||||
"staleSessionInactivityTimeout": 1800000,
|
||||
"staleSessionHeartbeatInterval": 180000,
|
||||
"staleSessionPurgeInterval": 60000,
|
||||
"staleSessionActivityEvents": "mousemove click keydown"
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,5 +15,11 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"public": {
|
||||
"staleSessionInactivityTimeout": 1800000,
|
||||
"staleSessionHeartbeatInterval": 180000,
|
||||
"staleSessionPurgeInterval": 60000,
|
||||
"staleSessionActivityEvents": "mousemove click keydown"
|
||||
}
|
||||
}
|
||||
@ -16,5 +16,11 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"public": {
|
||||
"staleSessionInactivityTimeout": 1800000,
|
||||
"staleSessionHeartbeatInterval": 180000,
|
||||
"staleSessionPurgeInterval": 60000,
|
||||
"staleSessionActivityEvents": "mousemove click keydown"
|
||||
}
|
||||
}
|
||||
@ -15,5 +15,11 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"public": {
|
||||
"staleSessionInactivityTimeout": 1800000,
|
||||
"staleSessionHeartbeatInterval": 180000,
|
||||
"staleSessionPurgeInterval": 60000,
|
||||
"staleSessionActivityEvents": "mousemove click keydown"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user