betajs/betajs-server

View on GitHub
src/sessions/active.js

Summary

Maintainability
B
4 hrs
Test Coverage
Scoped.define("module:Sessions.ActiveSessionHelper", [      
        "base:Class",
        "base:Classes.HelperClassMixin",
        "base:Lists.ObjectIdList",
        "base:Tokens"
    ], function (Class, HelperClassMixin, ObjectIdList, Tokens, scoped) {
    return Class.extend({scoped: scoped}, [HelperClassMixin, function (inherited) {
        return {
            
            constructor: function (session, helper) {
                inherited.constructor.call(this);
                this.__helper = helper;
                this.__session = session;
                session.active_sessions = this;
                this.__active_sessions = new ObjectIdList();
            },
            
            destroy: function () {
                this.iterate(function (active_session) {
                    active_session.destroy();
                }, this);
                this.__active_sessions.destroy();
                inherited.destroy.call(this);
            },
            
            session: function () {
                return this.__session;
            },
            
            helper: function () {
                return this.__helper;
            },
            
            invalidate: function () {
                this.iterate(function (active_session) {
                    active_session.invalidate();
                }, this);
            },
        
            iterate: function (cb, ctx) {
                this.__active_sessions.iterate(cb, ctx || this);
            },
            
            is_active: function () {
                return this.__active_sessions.count() > 0;
            },
            
            find_active_session: function (token) {
                return this.__active_sessions.get(token);
            },
            
            __generate_token: function () {
                return Tokens.generate_token();
            },
        
            __remove_active_session: function (active_session) {
                if (this.__active_sessions.exists(active_session)) {
                    this.__active_sessions.remove(active_session);
                    this.__session.activity();
                }
            },
            
            delete_active_session: function (active_session) {
                active_session.destroy();
            },
            
            obtain_active_session: function (token, options) {
                return this.find_active_session(token) || this.new_active_session(token, options);
            },
            
            __add_active_session: function (active_session) {
                this.__active_sessions.add(active_session);
                this.session().manager().__add_active_session(this.session(), active_session);
            },
        
            new_active_session: function (token, options) {
                var active_session = new this.__helper._active_session_class(this, token || this.__generate_token(), options);
                this.__add_active_session(active_session);
                return active_session;
            },
            
            continue_active_session: function (options) {
                var active_session = null;
                this.iterate(function (as) {
                    if (as.suspended() && as.can_continue(options)) {
                        active_session = as;
                        return false; 
                    }
                    return true;
                });
                return active_session;
            },
            
            attach_active_session: function (options) {
                return this.continue_active_session(options) || this.new_active_session(null, options);
            }
        
        };
    }]);
});




Scoped.define("module:Sessions.ActiveSession", [      
      "base:Class",
      "base:Classes.HelperClassMixin",
      "base:Events.EventsMixin",
      "base:Ids",
      "base:Time"
  ], function (Class, HelperClassMixin, EventsMixin, Ids, Time, scoped) {
  return Class.extend({scoped: scoped}, [HelperClassMixin, EventsMixin, function (inherited) {
      return {
        
            constructor: function (helper, token, options) {
                inherited.constructor.call(this);
                this.__helper = helper;
                this.__options = options || {};
                Ids.objectId(this, token);
                this.initiation_time = Time.now();
                this.active_time = this.initiation_time;
            },
            
            destroy: function () {
                this.trigger("destroy");
                this.__helper.__remove_active_session(this);
                inherited.destroy.call(this);
            },
            
            session: function () {
                return this.__helper.session();
            },
            
            options: function () {
                return this.__options;
            },
            
            activity: function () {
                this.active_time = Time.now();
            },
            
            suspended: function () {
                return this._helper({
                    method: "suspended",
                    fold_start: false,
                    fold: function (acc, result) {
                        return acc || result;
                    }
                });
            },
            
            can_continue: function (options) {
                return false;
            },
            
            invalidate: function () {
                var opts = this.__helper.helper().options().invalidation;
                var now = Time.now();
                if ((opts.active_session_timeout && now > this.initiation_time + opts.active_session_timeout) ||
                    (this.suspended() && opts.active_session_inactivity_timeout && now > this.active_time + opts.active_session_inactivity_timeout)) {
                    this.destroy();
                }
            }    
    
      };
  }]);    
});
            


Scoped.define("module:Sessions.ActiveSessionManagerHelper", [      
      "base:Class",
      "module:Sessions.ActiveSession",
      "module:Sessions.ActiveSessionHelper",
      "base:Objs",
      "base:Types"
  ], function (Class, ActiveSession, ActiveSessionHelper, Objs, Types, scoped) {
  return Class.extend({scoped: scoped}, function (inherited) {
      return {

            _active_session_class: ActiveSession,
        
            constructor: function (manager, options) {
                inherited.constructor.call(this);
                options = Objs.tree_extend({
                    invalidation: {
                        // All times are in milliseconds; null to disable
                        // hard timeout to remove active sessions
                        active_session_timeout: 1000 * 60 * 60,
                        // kill active session if there is no active session after time
                        active_session_inactivity_timeout: 1000 * 60
                    }
                }, options);
                this.__options = options;
                this._active_session_class = options.active_session_class || this._active_session_class;
                if (Types.is_string(this._active_session_class))
                    this._active_session_class = Scoped.getGlobal(this._active_session_class);
                manager.__add_active_session = function (session, active_session) {
                    this._helper("__add_active_session", session, active_session);
                };
            },
            
            __add_session: function (session) {
                session.addHelper(ActiveSessionHelper, this);
            },
            
            options: function () {
                return this.__options;
            }

      };
  });
});