c9-core/node_modules/connect-architect/connect.session.file/session-ext.js

170 wiersze
4.9 KiB
JavaScript

var assert = require("assert");
var path = require("path");
var fs = require("fs");
var Store = require("connect/lib/middleware/session/store");
module.exports = function startup(options, imports, register) {
assert(options.sessionsPath, "option 'sessionsPath' is required");
if (!path.existsSync(path.dirname(options.sessionsPath))) {
fs.mkdir(path.dirname(options.sessionsPath), 0755);
}
if (!path.existsSync(options.sessionsPath)) {
fs.mkdir(options.sessionsPath, 0755);
}
var sessionStore = new FileStore({
basePath: options.sessionsPath,
reapInterval: 60 * 60 * 1000 // 1 hour
});
register(null, {
"session-store": {
on: sessionStore.on.bind(sessionStore),
get: sessionStore.get.bind(sessionStore),
set: sessionStore.set.bind(sessionStore),
destroy: sessionStore.destroy.bind(sessionStore),
regenerate: sessionStore.regenerate.bind(sessionStore),
createSession: sessionStore.createSession.bind(sessionStore)
}
});
};
var FileStore = function(options) {
var self = this;
self.basePath = options.basePath;
self.reapInterval = options.reapInterval || -1;
if (self.reapInterval > 0) {
setInterval(function() {
fs.readdir(self.basePath, function(err, files) {
if (err) {
console.error(err);
return;
}
files.forEach(function(file) {
fs.readFile(self.basePath + "/" + file, function(err, data) {
if (err) {
console.error(err);
return;
}
var sess = JSON.parse(data);
var expires = (typeof sess.cookie.expires === 'string')
? new Date(sess.cookie.expires)
: sess.cookie.expires;
if (!expires || new Date < expires) {
// session ok
} else {
self.destroy(file);
}
});
});
});
}, self.reapInterval);
}
};
FileStore.prototype.__proto__ = Store.prototype;
FileStore.prototype.get = function(sid, fn){
var self = this;
sid = sid.replace(/\//g, "_");
path.exists(self.basePath + "/" + sid, function(exists) {
if (exists) {
fs.readFile(self.basePath + "/" + sid, function(err, data) {
if (err) {
fn && fn(err);
}
else {
var sess;
try {
sess = JSON.parse(data);
} catch(e) {
console.warn("Error '" + e + "' reading session: " + sid, data);
self.destroy(sid, fn);
return;
}
var expires = (typeof sess.cookie.expires === 'string')
? new Date(sess.cookie.expires)
: sess.cookie.expires;
if (!expires || new Date < expires) {
fn(null, sess);
} else {
self.destroy(sid, fn);
}
}
});
}
else {
fn();
}
});
};
FileStore.prototype.set = function(sid, sess, fn){
var self = this;
sid = sid.replace(/\//g, "_");
var path = self.basePath + "/" + sid;
var tmpPath = path + "~" + new Date().getTime();
fs.writeFile(path, JSON.stringify(sess), function(err) {
if (err)
return fn && fn(err);
fs.rename(tmpPath, path, function(err) {
fn && fn(err);
});
});
};
FileStore.prototype.destroy = function(sid, fn){
var self = this;
sid = sid.replace(/\//g, "_");
path.exists(self.basePath + "/" + sid, function(exists) {
if (exists) {
fs.unlink(self.basePath + "/" + sid, function(err) {
if (err) {
fn && fn(err);
}
else {
fn && fn();
}
});
} else {
fn && fn();
}
});
};
FileStore.prototype.all = function(fn){
var self = this;
fs.readdir(self.basePath, function(err, files) {
if (err) {
fn && fn(err);
return;
}
var arr = [];
files.forEach(function(file) {
// TODO: Make this async.
arr.push(JSON.parse(fs.readFileSync(self.basePath + "/" + file)));
});
fn && fn(arr);
});
};
FileStore.prototype.clear = function(fn){
throw new Error("NYI");
/*
this.sessions = {};
fn && fn();
*/
};
FileStore.prototype.length = function(fn){
throw new Error("NYI");
/*
fn(null, Object.keys(this.sessions).length);
*/
};