Socket
Socket
Sign inDemoInstall

flowstate

Package Overview
Dependencies
4
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.2 to 0.4.0

lib/middleware/complete.js

10

lib/index.js
exports.Manager = require('./manager');
exports.SessionStore = require('./stores/session');
exports.load = require('./middleware/load');
exports.resume = require('./middleware/resume');
exports.resumeError = require('./middleware/resumeError');
exports.clean = require('./middleware/clean');
exports.middleware = {};
exports.middleware.load = require('./middleware/load');
exports.middleware.complete = require('./middleware/complete');
exports.middleware.completeError = require('./middleware/completeError');
exports.middleware.clean = require('./middleware/clean');
exports.ExpiredStateError = require('./errors/expiredstateerror');
exports.MissingStateError = require('./errors/missingstateerror');

52

lib/manager.js

@@ -5,7 +5,9 @@ var flatten = require('utils-flatten');

function Manager() {
function Manager(store) {
this._flows = {};
this._stt = {};
this._store = store;
}
Manager.prototype.add = function(name, begin, resume) {
Manager.prototype.use = function(name, begin, resume) {
begin = begin && flatten(Array.prototype.slice.call(begin, 0));

@@ -20,3 +22,19 @@ resume = resume && flatten(Array.prototype.slice.call(resume, 0));

Manager.prototype.goto = function(name, req, res, next) {
Manager.prototype.transition = function(name, from, trans) {
if (!Array.isArray(trans)) {
trans = [ trans ];
}
trans = trans && flatten(Array.prototype.slice.call(trans, 0));
this._stt[name + '|' + from] = trans;
}
Manager.prototype.goto = function(name, options, req, res, next) {
if (typeof next !== 'function') {
next = res;
res = req;
req = options;
options = undefined;
}
var flow = this._flows[name];

@@ -26,9 +44,26 @@ if (!flow) { throw new Error("Cannot find flow '" + name + "'"); }

if (options) {
req.locals = options;
}
dispatch(flow.begin)(null, req, res, next);
}
Manager.prototype.loadState = function(options) {
return require('./middleware/load')(this._store, options);
};
Manager.prototype.complete = function(options) {
return require('./middleware/complete')(this, this._store, options);
};
Manager.prototype.completeError =
Manager.prototype.completeErrorHandler =
Manager.prototype.completeWithError = function(options) {
return require('./middleware/completeError')(this, this._store, options);
};
Manager.prototype._resume = function(name, err, req, res, next) {
var flow = this._flows[name];
if (!flow) { throw new Error("Cannot find flow '" + name + "'"); }
if (!flow.resume) { throw new Error("Cannot resume flow '" + name + "'"); }
if (!flow) { return next(new Error("Cannot find flow '" + name + "'")); }
if (!flow.resume) { return next(new Error("Cannot resume flow '" + name + "'")); }

@@ -38,3 +73,10 @@ dispatch(flow.resume)(err, req, res, next);

Manager.prototype._transition = function(name, from, err, req, res, next) {
var trans = this._stt[name + '|' + from];
if (!trans) { return next(err); }
dispatch(trans)(err, req, res, next);
}
module.exports = Manager;

@@ -0,7 +1,34 @@

/**
* Module dependencies.
*/
var SessionStore = require('../stores/session');
/**
* Load state.
*
* This middleware is used to load state associated with a request. The state
* will be made available at `req.state`.
*
* HTTP is a stateless protocol. In order to support stateful interactions, the
* client and server need to operate in coordination. The server is responsible
* for persisting state associated with a request. The client is responsible for
* indicating that state in subsequent requests to the server (via a `state`
* parameter in the query or body, by default). The server then loads the
* previously persisted state in order to continue processing the transaction.
*
* Options:
*
* name set req.state only if the state name is equal to the option value
*
* @return {Function}
* @api public
*/
module.exports = function(store, options) {
if (typeof options == 'string') {
options = { name: options };
}
options = options || {};
var name = options.name;
var getHandle = options.getHandle || function(req) {

@@ -11,10 +38,26 @@ return (req.query && req.query.state) || (req.body && req.body.state);

return function loadState(req, res, next) {
var h = getHandle(req);
if (!h) { return next(); }
if (!h) {
if (options.required) {
return next(new Error("Failed to load required state '" + name + "'"));
}
return next();
}
store.load(req, h, function (err, state) {
if (err) { return next(err); }
req.state = state;
if (!name) {
req.state = state;
} else if (name == state.name) {
req.state = state;
} else {
// The loaded state is not the expected state. Save what was loaded,
// as an optimization to avoid re-loading later if the state is resumed.
req._state = state;
}
if (options.required && !req.state) {
return next(new Error("Failed to load required state '" + name + "'"));
}
next();

@@ -21,0 +64,0 @@ });

@@ -58,11 +58,13 @@ var uid = require('uid-safe').sync;

SessionStore.prototype.save = function(req, state, cb) {
state.initiatedAt = Date.now();
if (req.state && req.state.handle) {
state.prev = req.state.handle;
SessionStore.prototype.save = function(req, state, options, cb) {
if (typeof options == 'function') {
cb = options;
options = undefined;
}
options = options || {};
state.initiatedAt = state.initiatedAt || Date.now();
var key = this._key;
var h = uid(24);
var h = options.h || uid(8);
req.session[key] = req.session[key] || {};

@@ -75,6 +77,3 @@ req.session[key][h] = clone(state);

SessionStore.prototype.update = function(req, h, state, cb) {
if (req.state && req.state.handle == h) {
state.initiatedAt = req.state.initiatedAt;
if (req.state.prev) { state.prev = req.state.prev; }
}
if (state.handle === h) { delete state.handle; }

@@ -85,3 +84,3 @@ var key = this._key;

return cb(null);
return cb(null, h);
}

@@ -88,0 +87,0 @@

{
"name": "flowstate",
"version": "0.3.2",
"version": "0.4.0",
"description": "Stateful, transactional flows using page-based navigation.",

@@ -28,3 +28,5 @@ "author": {

"mocha": "^2.0.0",
"chai": "^3.0.0"
"chai": "^3.0.0",
"sinon-chai": "^2.8.0",
"chai-connect-middleware": "0.3.x"
},

@@ -31,0 +33,0 @@ "scripts": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc