- requireRegexValidation toggles whether or not password validation is controlled by regular expression - requireStrongPasswords toggles whether password validation is controlled by zxcvbn package LT-104: User account shall be locked after 5 failed attempts - "failedAttemptsLimit" property which is under passwordOptions in ActiveEntry configuration object sets number of failed attempts count to lock user account, it is set 5 as default LT-99: Passwords shall use password history of 6 - "passwordHistoryCount" property which is under passwordOptions in ActiveEntry configuration object sets count of last passwords that is not used to reset password - Show error messages in changePassword template - Make signIn button disabled if inputs are not validated
87 lines
3.9 KiB
JavaScript
87 lines
3.9 KiB
JavaScript
//
|
|
// Client side activity detection for the session timeout
|
|
// - depends on jquery
|
|
//
|
|
// Meteor settings:
|
|
// - staleSessionHeartbeatInterval: interval (in ms) at which activity heartbeats are sent up to the server
|
|
// - staleSessionActivityEvents: the jquery events which are considered indicator of activity e.g. in an on() call.
|
|
//
|
|
var heartbeatInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionHeartbeatInterval || (3*60*1000); // 3mins
|
|
var activityEvents = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionActivityEvents || 'mousemove click keydown';
|
|
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
|
|
|
|
var dialogTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.dialogTimeout || (30*1000); // 30secs
|
|
var showCountdownDialog = Meteor.settings && Meteor.settings.public && Meteor.settings.public.showCountdownDialog || false;
|
|
var countdownHeartbeatInterval = (heartbeatInterval < dialogTimeout)? heartbeatInterval : dialogTimeout;
|
|
|
|
var activityDetected = false;
|
|
var lastActivityDetectedTime = new Date();
|
|
var dialogIsOpen = false;
|
|
|
|
Meteor.startup(function() {
|
|
|
|
//
|
|
// periodically send a heartbeat if activity has been detected within the interval
|
|
//
|
|
if (showCountdownDialog) {
|
|
Meteor.setInterval(function() {
|
|
if (Meteor.userId()) {
|
|
if (activityDetected) {
|
|
Meteor.call('heartbeat', function(error, heartbeatTime) {
|
|
lastActivityDetectedTime = heartbeatTime;
|
|
activityDetected = false;
|
|
// Event to close dialog
|
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
|
dialogIsOpen = false;
|
|
});
|
|
|
|
} else {
|
|
var overdueTimestamp = new Date().getTime() - lastActivityDetectedTime;
|
|
// Ignore min differences
|
|
overdueTimestamp = overdueTimestamp - (overdueTimestamp % 1000);
|
|
console.log(overdueTimestamp);
|
|
var startTime = inactivityTimeout - dialogTimeout;
|
|
var nextIntervalTime = overdueTimestamp + countdownHeartbeatInterval;
|
|
if (overdueTimestamp <= inactivityTimeout && nextIntervalTime <= inactivityTimeout && nextIntervalTime >= startTime) {
|
|
if (Math.abs(startTime - overdueTimestamp) <= Math.abs(nextIntervalTime - startTime) && !dialogIsOpen) {
|
|
// Open dialog
|
|
var leftTime = Math.round((inactivityTimeout - overdueTimestamp) / 1000);
|
|
$.event.trigger('TriggerOpenTimeoutCountdownDialog', leftTime);
|
|
dialogIsOpen = true;
|
|
}
|
|
|
|
} else {
|
|
// Event to close dialog
|
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
|
dialogIsOpen = false;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
// Event to close dialog
|
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
|
dialogIsOpen = false;
|
|
}
|
|
}, countdownHeartbeatInterval);
|
|
|
|
} else{
|
|
|
|
Meteor.setInterval(function() {
|
|
if (Meteor.userId() && activityDetected) {
|
|
Meteor.call('heartbeat');
|
|
activityDetected = false;
|
|
}
|
|
}, heartbeatInterval);
|
|
}
|
|
|
|
//
|
|
// detect activity and mark it as detected on any of the following events
|
|
//
|
|
$(document).on(activityEvents, function() {
|
|
activityDetected = true;
|
|
// Event to close dialog
|
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
|
dialogIsOpen = false;
|
|
});
|
|
});
|