mirror of https://gitee.com/bigwinds/arangodb
170 lines
4.3 KiB
JavaScript
170 lines
4.3 KiB
JavaScript
/*global require, exports, applicationContext */
|
|
(function () {
|
|
'use strict';
|
|
var _ = require('underscore'),
|
|
joi = require('joi'),
|
|
internal = require('internal'),
|
|
arangodb = require('org/arangodb'),
|
|
db = arangodb.db,
|
|
Foxx = require('org/arangodb/foxx'),
|
|
errors = require('./errors'),
|
|
cfg = applicationContext.configuration,
|
|
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()
|
|
}
|
|
}),
|
|
sessions = new Foxx.Repository(
|
|
applicationContext.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),
|
|
now = Number(new Date()),
|
|
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);
|
|
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);
|
|
}
|
|
});
|
|
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 () {
|
|
if (!cfg.timeToLive) {
|
|
return Infinity;
|
|
}
|
|
return Math.max(0, this.getExpiry() - Date.now());
|
|
},
|
|
getExpiry: function () {
|
|
if (!cfg.timeToLive) {
|
|
return Infinity;
|
|
}
|
|
var prop = cfg.ttlType;
|
|
if (!prop || !this.get(prop)) {
|
|
prop = 'created';
|
|
}
|
|
return this.get(prop) + cfg.timeToLive;
|
|
},
|
|
setUser: function (user) {
|
|
var session = this;
|
|
if (user) {
|
|
session.set('uid', user.get('_id'));
|
|
session.set('userData', user.get('userData'));
|
|
} else {
|
|
delete session.attributes.uid;
|
|
session.set('userData', {});
|
|
}
|
|
return session;
|
|
},
|
|
save: function () {
|
|
var session = this,
|
|
now = Number(new Date());
|
|
session.set('lastAccess', now);
|
|
session.set('lastUpdate', now);
|
|
sessions.replace(session);
|
|
return session;
|
|
},
|
|
delete: function () {
|
|
var session = this,
|
|
now = Number(new Date());
|
|
session.set('lastAccess', now);
|
|
session.set('lastUpdate', now);
|
|
try {
|
|
deleteSession(session.get('_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;
|
|
}()); |