LT-107: Add correct meteor-stale-session
This commit is contained in:
parent
360d674049
commit
d18a66d513
20
Packages/meteor-stale-session/LICENSE
Normal file
20
Packages/meteor-stale-session/LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Chris Lindley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
58
Packages/meteor-stale-session/README.md
Normal file
58
Packages/meteor-stale-session/README.md
Normal file
@ -0,0 +1,58 @@
|
||||
# zuuk:stale-session
|
||||
|
||||
Stale session and session timeout handling for [meteorjs](http://www.meteor.com/).
|
||||
|
||||
## Quick Start
|
||||
|
||||
```sh
|
||||
$ meteor add zuuk:stale-session
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
When a user logs in to a meteor application, they may gain access to privileged information and functionality. If they neglect to log off, another user of the same computer can effectively impersonate that user and gains the same rights. As it currently stands, (meteor 0.6.6.3), login tokens remain valid for eternity so this creates a large window of opportunity for impersonators.
|
||||
|
||||
This package is designed to detect a user's inactivity and automatically log them off after a configurable amount of time thereby reducing the size of this window to just the inactivity delay.
|
||||
|
||||
It is possible to configure both the timeout and the events that consitute activity.
|
||||
|
||||
The user will be logged off whether the browser window remains open or not.
|
||||
|
||||
The user is logged off by the server and disabling javascript in the browser (kind of pointless in meteor!) would not prevent automatic log off.
|
||||
|
||||
The user can be logged on multiple times on multiple devices and activity in any one of those devices will keep the sessions alive.
|
||||
|
||||
The plugin uses a heartbeat that is configurable but defaulted to ensure that the server is not inundated with heartbeats from clients in systems with many concurrent users.
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration is via `Meteor.settings.public`.
|
||||
|
||||
- `staleSessionInactivityTimeout` - the amount of time (in ms) after which, if no activity is noticed, a session will be considered stale - default 30 minutes.
|
||||
- `staleSessionPurgeInterval` - interval (in ms) at which stale sessions are purged i.e. found and forcibly logged out - default 1 minute.
|
||||
- `staleSessionHeartbeatInterval` - interval (in ms) at which activity heartbeats are sent up to the server - default every 3 minutes.
|
||||
- `staleSessionActivityEvents` - the jquery events which are considered indicator of activity e.g. in an on() call - default `mousemove click keydown`
|
||||
|
||||
You can set these variables in `config/settings.json` and then launch Meteor with `meteor --settings config/settings.json`.
|
||||
|
||||
Example `config/settings.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"public": {
|
||||
"staleSessionInactivityTimeout": 1800000,
|
||||
"staleSessionHeartbeatInterval": 180000,
|
||||
"staleSessionPurgeInterval": 60000,
|
||||
"staleSessionActivityEvents": "mousemove click keydown"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Background
|
||||
|
||||
A meteor project I was working on at [ZUUK](http://www.zuuk.com/), required user sessions to timeout after a period of inactivity. Meteor itself doesn't currently (0.6.6.3) support this out of the box and, though there were several plugins already available on [Atmosphere](https://atmosphere.meteor.com/), none of them worked reliably for me so I was forced to create my own for the project. I owe those other packages a great deal of gratitude as this package is effectively just taking ideas from them and making them work in a simpler more reliable fashion for my project. I'm putting this back into the community in the hope it will help in the same situation.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
82
Packages/meteor-stale-session/client.js
Normal file
82
Packages/meteor-stale-session/client.js
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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 countdownDialogTime = Meteor.settings && Meteor.settings.public && Meteor.settings.public.countdownDialogTime || (15*1000); // 30second
|
||||
var showCountdownDialog = Meteor.settings && Meteor.settings.public && Meteor.settings.public.showCountdownDialog || true;
|
||||
|
||||
var activityDetected = false;
|
||||
var activityDetectedTime = new Date();
|
||||
|
||||
Meteor.startup(function() {
|
||||
// Add countdown dialog to body
|
||||
$("body").append('<div id="staleSessionCountdownModal" title="Session will expire!"></div>');
|
||||
|
||||
//Initialize the dialog
|
||||
$("#staleSessionCountdownModal").dialog({
|
||||
autoOpen: false,
|
||||
open: function(){
|
||||
$('.ui-widget-overlay').bind('click',function(){
|
||||
$('#staleSessionCountdownModal').dialog('close');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// periodically send a heartbeat if activity has been detected within the interval
|
||||
//
|
||||
Meteor.setInterval(function() {
|
||||
if (Meteor.userId() && activityDetected) {
|
||||
Meteor.call('heartbeat');
|
||||
activityDetected = false;
|
||||
}
|
||||
}, heartbeatInterval);
|
||||
|
||||
// Detect the time when countdown dialog will be shown
|
||||
if (showCountdownDialog) {
|
||||
Meteor.setInterval(function() {
|
||||
if (!activityDetected) {
|
||||
var lastHeartbeatTime = activityDetectedTime.getTime();
|
||||
var now = new Date().getTime();
|
||||
var overdueTimestamp = now - lastHeartbeatTime;
|
||||
var dialogTime = inactivityTimeout - countdownDialogTime;
|
||||
if(dialogTime <= overdueTimestamp && inactivityTimeout >= overdueTimestamp) {
|
||||
var sec = Math.round((inactivityTimeout - overdueTimestamp) / 1000);
|
||||
console.log(sec);
|
||||
var dialogStr = "You will be log out in "+sec+" seconds.";
|
||||
if (sec === 0) {
|
||||
$("#staleSessionCountdownModal").dialog('close');
|
||||
} else {
|
||||
if(sec === 1) {
|
||||
dialogStr = "You will be log out in "+sec+" second.";
|
||||
}
|
||||
$('#staleSessionCountdownModal').html(dialogStr);
|
||||
$("#staleSessionCountdownModal").dialog('open');
|
||||
|
||||
// Remove border of close button
|
||||
$(".ui-button:focus").css("outline", "none");
|
||||
}
|
||||
|
||||
} else {
|
||||
$("#staleSessionCountdownModal").dialog('close');
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
//
|
||||
// detect activity and mark it as detected on any of the following events
|
||||
//
|
||||
$(document).on(activityEvents, function(event) {
|
||||
activityDetected = true;
|
||||
activityDetectedTime = new Date();
|
||||
$("#staleSessionCountdownModal").dialog('close');
|
||||
});
|
||||
});
|
||||
14
Packages/meteor-stale-session/package.js
Normal file
14
Packages/meteor-stale-session/package.js
Normal file
@ -0,0 +1,14 @@
|
||||
Package.describe({
|
||||
name: 'zuuk:stale-session',
|
||||
summary: 'Stale session and session timeout handling for meteorjs',
|
||||
git: "https://github.com/lindleycb/meteor-stale-session.git",
|
||||
version: "1.0.8"
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.use('accounts-base@1.0.0', ['client','server']);
|
||||
api.use('jquery@1.0.0', 'client');
|
||||
api.use('mizzao:jquery-ui', 'client');
|
||||
api.addFiles('client.js', 'client');
|
||||
api.addFiles('server.js', 'server');
|
||||
});
|
||||
35
Packages/meteor-stale-session/server.js
Normal file
35
Packages/meteor-stale-session/server.js
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Server side activity detection for the session timeout
|
||||
//
|
||||
// Meteor settings:
|
||||
// - staleSessionInactivityTimeout: the amount of time (in ms) after which, if no activity is noticed, a session will be considered stale
|
||||
// - staleSessionPurgeInterval: interval (in ms) at which stale sessions are purged i.e. found and forcibly logged out
|
||||
//
|
||||
var staleSessionPurgeInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionPurgeInterval || (1*60*1000); // 1min
|
||||
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
|
||||
|
||||
//
|
||||
// provide a user activity heartbeat method which stamps the user record with a timestamp of the last
|
||||
// received activity heartbeat.
|
||||
//
|
||||
Meteor.methods({
|
||||
heartbeat: function(options) {
|
||||
if (!this.userId) { return; }
|
||||
var user = Meteor.users.findOne(this.userId);
|
||||
if (user) {
|
||||
Meteor.users.update(user._id, {$set: {heartbeat: new Date()}});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//
|
||||
// periodically purge any stale sessions, removing their login tokens and clearing out the stale heartbeat.
|
||||
//
|
||||
Meteor.setInterval(function() {
|
||||
var now = new Date(), overdueTimestamp = new Date(now-inactivityTimeout);
|
||||
Meteor.users.update({heartbeat: {$lt: overdueTimestamp}},
|
||||
{$set: {'services.resume.loginTokens': []},
|
||||
$unset: {heartbeat:1}},
|
||||
{multi: true});
|
||||
}, staleSessionPurgeInterval);
|
||||
Loading…
Reference in New Issue
Block a user