forked from valery-barysok/session-file-store
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
992b564
commit 0ca45f7
Showing
5 changed files
with
312 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
############################ | ||
# npm | ||
############################ | ||
node_modules | ||
npm-debug.log | ||
|
||
|
||
############################ | ||
# tmp, editor & OS files | ||
############################ | ||
.tmp | ||
*.swo | ||
*.swp | ||
*.swn | ||
*.swm | ||
.DS_STORE | ||
*# | ||
*~ | ||
.idea | ||
nbproject | ||
|
||
|
||
############################ | ||
# Other | ||
############################ | ||
.node_history |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = function(session) { | ||
return require('./lib/session-file-store')(session); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
var fs = require('graceful-fs'), | ||
path = require('path'), | ||
retry = require("retry"); | ||
|
||
/** | ||
* One day in seconds | ||
*/ | ||
|
||
var ONE_DAY = 24 * 60 * 60; | ||
|
||
/** | ||
* https://github.com/expressjs/session#session-store-implementation | ||
* | ||
* @param {object} session express session | ||
* @return {Function} the `FileStore` extending `express`'s session Store | ||
* | ||
* @api public | ||
*/ | ||
module.exports = function (session) { | ||
var Store = session.Store; | ||
|
||
/** | ||
* Initialize FileStore with the given `options` | ||
* | ||
* @param {Object} options | ||
* @api public | ||
*/ | ||
function FileStore(options) { | ||
var self = this; | ||
|
||
options = options || {}; | ||
Store.call(self, options); | ||
|
||
self.path = path.normalize(options.path || './sessions'); | ||
self.ttl = options.ttl; | ||
self.retries = options.retries || 5; | ||
self.factor = options.factor || 1; | ||
self.minTimeout = options.minTimeout || 50; | ||
self.maxTimeout = options.maxTimeout || 50; | ||
|
||
self.filePattern = /\.json$/; | ||
|
||
fs.mkdir(self.path, function (err) { | ||
if (err && err.code != 'EEXIST') throw err; | ||
}); | ||
} | ||
|
||
/** | ||
* Inherit from Store | ||
*/ | ||
FileStore.prototype.__proto__ = Store.prototype; | ||
|
||
/** | ||
* Attempts to fetch session from a session file by the given `sessionId` | ||
* | ||
* @param {String} sessionId | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.get = function (sessionId, callback) { | ||
var self = this; | ||
|
||
var sessionPath = path.join(this.path, sessionId + '.json'), | ||
json; | ||
|
||
var operation = retry.operation({ | ||
retries: self.retries, | ||
factor: self.factor, | ||
minTimeout: self.minTimeout, | ||
maxTimeout: self.maxTimeout | ||
}); | ||
|
||
operation.attempt(function (currentAttempt) { | ||
fs.readFile(sessionPath, 'utf8', function (err, data) { | ||
if (err) return callback(err); | ||
|
||
try { | ||
json = JSON.parse(data); | ||
} catch (err) { | ||
if (operation.retry(err)) { | ||
console.log("[retry] will retry, error on last attempt: " + err); | ||
return; | ||
} | ||
return callback(err); | ||
} | ||
|
||
callback(null, json); | ||
}); | ||
}); | ||
}; | ||
|
||
/** | ||
* Attempts to commit the given session associated with the given `sessionId` to a session file | ||
* | ||
* @param {String} sessionId | ||
* @param {Object} session | ||
* @param {Function} callback optional | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.set = function (sessionId, session, callback) { | ||
var self = this; | ||
|
||
try { | ||
session.__lastAccess = new Date().getTime(); | ||
session = JSON.stringify(session); | ||
|
||
fs.writeFile(path.join(self.path, sessionId + '.json'), session, function (err) { | ||
callback && err ? callback(err) : callback(null, JSON.parse(session)); | ||
}); | ||
} catch (err) { | ||
callback && callback(err); | ||
} | ||
}; | ||
|
||
/** | ||
* Attempts to unlink a given session by its id | ||
* | ||
* @param {String} sessionId Files are serialized to disk by their | ||
* sessionId | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.destroy = function (sessionId, callback) { | ||
fs.unlink(path.join(this.path, sessionId + '.json'), function (err) { | ||
err && callback(err); | ||
}); | ||
}; | ||
|
||
/** | ||
* Attempts to fetch number of the session files | ||
* | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.length = function (callback) { | ||
var self = this; | ||
|
||
fs.readdir(self.path, function (err, files) { | ||
if (err) return callback(err); | ||
|
||
var result = 0; | ||
files.forEach(function (file) { | ||
if (self.filePattern.exec(file)) { | ||
++result; | ||
} | ||
}); | ||
|
||
callback(null, result); | ||
}); | ||
}; | ||
|
||
/** | ||
* Attempts to clear out all of the existing session files | ||
* | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.clear = function (callback) { | ||
var self = this, | ||
filePath; | ||
|
||
fs.readdir(self.path, function (err, files) { | ||
if (files.length <= 0) return callback(); | ||
|
||
var errors = []; | ||
files.forEach(function (file, i) { | ||
filePath = path.join(self.path, file); | ||
|
||
if (self.filePattern.exec(file)) { | ||
fs.unlink(filePath, function (err) { | ||
if (err) { | ||
errors.push(err); | ||
} | ||
if (i >= files.length - 1) { | ||
callback(errors.length > 0 ? errors : undefined); | ||
} | ||
}); | ||
} else { | ||
if (i >= files.length - 1) { | ||
callback(errors.length > 0 ? errors : undefined); | ||
} | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
/** | ||
* Attempts to find all of the session files | ||
* | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.list = function (callback) { | ||
var self = this; | ||
|
||
fs.readdir(self.path, function (err, files) { | ||
if (err) return callback(err); | ||
|
||
var sessionFiles = files.filter(function (file) { | ||
return self.filePattern.exec(file); | ||
}); | ||
|
||
callback(null, sessionFiles); | ||
}); | ||
}; | ||
|
||
/** | ||
* Attempts to detect whether a session file is already expired or not | ||
* | ||
* @param {String} sessionId | ||
* @param {Function} callback | ||
* | ||
* @api public | ||
*/ | ||
FileStore.prototype.expired = function (sessionId, callback) { | ||
var self = this, | ||
now = new Date().getTime(); | ||
self.get(sessionId, function (err, session) { | ||
if (err) return callback(err); | ||
|
||
var maxAge = session.cookie.maxAge, | ||
ttl = self.ttl || ('number' == typeof maxAge | ||
? maxAge / 1000 | 0 | ||
: ONE_DAY); | ||
|
||
err ? callback(err) : callback(null, session.__lastAccess + ttl < now); | ||
}); | ||
}; | ||
|
||
return FileStore; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "session-file-store", | ||
"version": "1.0.0", | ||
"description": "Session file store is a provision for storing session data in the session file", | ||
"main": "index.js", | ||
"private": false, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/valery-barysok/session-file-store" | ||
}, | ||
"keywords": [ | ||
"session", | ||
"file", | ||
"store" | ||
], | ||
"author": { | ||
"name": "Valery Barysok" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "Apache-2.0", | ||
"url": "http://www.apache.org/licenses/LICENSE-2.0" | ||
} | ||
], | ||
"bugs": { | ||
"url": "https://github.com/valery-barysok/session-file-store/issues" | ||
}, | ||
"homepage": "https://github.com/valery-barysok/session-file-store", | ||
"dependencies": { | ||
"graceful-fs": "^3.0.3", | ||
"retry": "^0.6.1" | ||
} | ||
} |