mirror of https://gitee.com/bigwinds/arangodb
172 lines
4.1 KiB
JavaScript
172 lines
4.1 KiB
JavaScript
/*global applicationContext */
|
|
'use strict';
|
|
|
|
var _ = require('underscore');
|
|
var joi = require('joi');
|
|
var internal = require('internal');
|
|
var arangodb = require('org/arangodb');
|
|
var db = arangodb.db;
|
|
var Foxx = require('org/arangodb/foxx');
|
|
var errors = require('./errors');
|
|
var cfg = applicationContext.configuration;
|
|
|
|
var Session = Foxx.Model.extend({
|
|
schema: {
|
|
_key: joi.string().required(),
|
|
uid: joi.string().optional(),
|
|
sessionData: joi.object().required(),
|
|
userData: joi.object().required(),
|
|
created: joi.number().integer().required(),
|
|
lastAccess: joi.number().integer().required(),
|
|
lastUpdate: joi.number().integer().required()
|
|
}
|
|
});
|
|
|
|
var sessions = new Foxx.Repository(
|
|
db._collection('_sessions'),
|
|
{model: Session}
|
|
);
|
|
|
|
function generateSessionId() {
|
|
var sid = '';
|
|
if (cfg.sidTimestamp) {
|
|
sid = internal.base64Encode(Number(new Date()));
|
|
if (cfg.sidLength === 0) {
|
|
return sid;
|
|
}
|
|
sid += '-';
|
|
}
|
|
return sid + internal.genRandomAlphaNumbers(cfg.sidLength || 10);
|
|
}
|
|
|
|
function createSession(sessionData) {
|
|
var sid = generateSessionId(cfg);
|
|
var now = Number(new Date());
|
|
var session = new Session({
|
|
_key: sid,
|
|
uid: null,
|
|
sessionData: sessionData || {},
|
|
userData: {},
|
|
created: now,
|
|
lastAccess: now,
|
|
lastUpdate: now
|
|
});
|
|
sessions.save(session);
|
|
return session;
|
|
}
|
|
|
|
function getSession(sid) {
|
|
var session;
|
|
db._executeTransaction({
|
|
collections: {
|
|
read: [sessions.collection.name()],
|
|
write: [sessions.collection.name()]
|
|
},
|
|
action: function () {
|
|
try {
|
|
session = sessions.byId(sid);
|
|
|
|
var accessTime = internal.accessSid(sid);
|
|
session.set('lastAccess', accessTime);
|
|
|
|
session.enforceTimeout();
|
|
} catch (err) {
|
|
if (
|
|
err instanceof arangodb.ArangoError
|
|
&& err.errorNum === arangodb.ERROR_ARANGO_DOCUMENT_NOT_FOUND
|
|
) {
|
|
throw new errors.SessionNotFound(sid);
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
var now = Number(new Date());
|
|
sessions.collection.update(session.forDB(), {
|
|
lastAccess: now
|
|
});
|
|
session.set('lastAccess', now);
|
|
session.save();
|
|
}
|
|
});
|
|
return session;
|
|
}
|
|
|
|
function deleteSession(sid) {
|
|
try {
|
|
sessions.removeById(sid);
|
|
} catch (err) {
|
|
if (
|
|
err instanceof arangodb.ArangoError
|
|
&& err.errorNum === arangodb.ERROR_ARANGO_DOCUMENT_NOT_FOUND
|
|
) {
|
|
throw new errors.SessionNotFound(sid);
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
_.extend(Session.prototype, {
|
|
enforceTimeout: function () {
|
|
if (this.hasExpired()) {
|
|
throw new errors.SessionExpired(this.get('_key'));
|
|
}
|
|
},
|
|
hasExpired: function () {
|
|
return this.getTTL() === 0;
|
|
},
|
|
getTTL: function () {
|
|
return Math.max(0, this.getExpiry() - Date.now());
|
|
},
|
|
getExpiry: function () {
|
|
return this.get('lastAccess') + (Number(internal.options()['server.session-timeout']) * 1000);
|
|
},
|
|
setUser: function (user) {
|
|
var session = this;
|
|
if (user) {
|
|
session.set('uid', user.get('_id'));
|
|
session.set('userData', user.get('userData'));
|
|
internal.createSid(session.get('_key'), user.get('user'));
|
|
} else {
|
|
delete session.attributes.uid;
|
|
session.set('userData', {});
|
|
internal.clearSid(session.get('_key'));
|
|
}
|
|
return session;
|
|
},
|
|
save: function () {
|
|
var session = this;
|
|
var now = Number(new Date());
|
|
session.set('lastAccess', now);
|
|
session.set('lastUpdate', now);
|
|
sessions.replace(session);
|
|
return session;
|
|
},
|
|
delete: function () {
|
|
var session = this;
|
|
var now = Number(new Date());
|
|
session.set('lastAccess', now);
|
|
session.set('lastUpdate', now);
|
|
try {
|
|
var key = session.get('_key');
|
|
internal.clearSid(key);
|
|
deleteSession(key);
|
|
return true;
|
|
} catch (e) {
|
|
if (e instanceof errors.SessionNotFound) {
|
|
return false;
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
});
|
|
|
|
exports.create = createSession;
|
|
exports.get = getSession;
|
|
exports.delete = deleteSession;
|
|
exports.errors = errors;
|
|
exports.repository = sessions;
|
|
exports._generateSessionId = generateSessionId;
|