kopia lustrzana https://github.com/c9/core
170 wiersze
4.9 KiB
JavaScript
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);
|
|
*/
|
|
};
|