mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
Session auth service (#9910)
refs #9865 * This service handles the session store and exporting middleware to be used for creating and managing sessions * Updates the auth service index.js file in line with how we do things elsewhere * After wrapping the exports in a getter, the usage of rewire had broken the authenticate tests, this commit _removes_ rewire from the tests, calls `init` on the models before the tests (needed because rewire isn't there) and also cleans up the use of var.
This commit is contained in:
parent
6cd1dc8005
commit
cb0c5dc582
@ -1,13 +1,25 @@
|
||||
var passport = require('./passport'),
|
||||
authorize = require('./authorize'),
|
||||
authenticate = require('./authenticate'),
|
||||
oauth = require('./oauth');
|
||||
module.exports = {
|
||||
get authorize() {
|
||||
return require('./authorize');
|
||||
},
|
||||
|
||||
exports.init = function (options) {
|
||||
oauth.init(options);
|
||||
return passport.init(options);
|
||||
get authenticate() {
|
||||
return require('./authenticate');
|
||||
},
|
||||
|
||||
get session() {
|
||||
return require('./session');
|
||||
},
|
||||
/*
|
||||
* TODO: Get rid of these when v0.1 is gone
|
||||
*/
|
||||
get init() {
|
||||
return (options) => {
|
||||
require('./oauth').init(options);
|
||||
return require('./passport').init(options);
|
||||
};
|
||||
},
|
||||
get oauth() {
|
||||
return require('./oauth');
|
||||
}
|
||||
};
|
||||
|
||||
exports.oauth = oauth;
|
||||
exports.authorize = authorize;
|
||||
exports.authenticate = authenticate;
|
||||
|
23
core/server/services/auth/session/index.js
Normal file
23
core/server/services/auth/session/index.js
Normal file
@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
get getSession() {
|
||||
return require('./middleware').getSession;
|
||||
},
|
||||
get cookieCsrfProtection() {
|
||||
return require('./middleware').cookieCsrfProtection;
|
||||
},
|
||||
get safeGetSession() {
|
||||
return require('./middleware').safeGetSession;
|
||||
},
|
||||
get createSession() {
|
||||
return require('./middleware').createSession;
|
||||
},
|
||||
get destroySession() {
|
||||
return require('./middleware').destroySession;
|
||||
},
|
||||
get getUser() {
|
||||
return require('./middleware').getUser;
|
||||
},
|
||||
get ensureUser() {
|
||||
return require('./middleware').ensureUser;
|
||||
}
|
||||
};
|
124
core/server/services/auth/session/middleware.js
Normal file
124
core/server/services/auth/session/middleware.js
Normal file
@ -0,0 +1,124 @@
|
||||
const {URL} = require('url');
|
||||
const common = require('../../../lib/common');
|
||||
const constants = require('../../../lib/constants');
|
||||
const config = require('../../../config');
|
||||
const settingsCache = require('../../settings/cache');
|
||||
const models = require('../../../models');
|
||||
const session = require('express-session');
|
||||
const SessionStore = require('./store');
|
||||
const urlService = require('../../url');
|
||||
|
||||
const getOrigin = (req) => {
|
||||
const origin = req.get('origin');
|
||||
const referrer = req.get('referrer');
|
||||
|
||||
if (!origin && !referrer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (origin) {
|
||||
return origin;
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL(req.get('referrer')).origin;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
let UNO_SESSIONIONA;
|
||||
const getSession = (req, res, next) => {
|
||||
if (!UNO_SESSIONIONA) {
|
||||
UNO_SESSIONIONA = session({
|
||||
store: new SessionStore(models.Session),
|
||||
secret: settingsCache.get('session_secret'),
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
name: 'ghost-admin-api-session',
|
||||
cookie: {
|
||||
maxAge: constants.SIX_MONTH_MS,
|
||||
httpOnly: true,
|
||||
path: '/ghost',
|
||||
sameSite: 'lax',
|
||||
secure: urlService.utils.isSSL(config.get('url'))
|
||||
}
|
||||
});
|
||||
}
|
||||
return UNO_SESSIONIONA(req, res, next);
|
||||
};
|
||||
|
||||
const createSession = (req, res, next) => {
|
||||
getSession(req, res, function () {
|
||||
const origin = getOrigin(req);
|
||||
if (!origin) {
|
||||
return next(new common.errors.BadRequestError({
|
||||
message: common.i18n.t('errors.middleware.auth.unknownOrigin')
|
||||
}));
|
||||
}
|
||||
req.session.user_id = req.user.id;
|
||||
req.session.origin = origin;
|
||||
req.session.user_agent = req.get('user-agent');
|
||||
req.session.ip = req.ip;
|
||||
res.sendStatus(201);
|
||||
});
|
||||
};
|
||||
|
||||
const destroySession = (req, res, next) => {
|
||||
req.session.destroy((err) => {
|
||||
if (err) {
|
||||
return next(new common.errors.InternalServerError({err}));
|
||||
}
|
||||
return res.sendStatus(204);
|
||||
});
|
||||
};
|
||||
|
||||
const getUser = (req, res, next) => {
|
||||
if (!req.session || !req.session.user_id) {
|
||||
req.user = null;
|
||||
return next();
|
||||
}
|
||||
models.User.findOne({id: req.session.user_id})
|
||||
.then((user) => {
|
||||
req.user = user;
|
||||
next();
|
||||
}).catch(() => {
|
||||
req.user = null;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const ensureUser = (req, res, next) => {
|
||||
if (req.user && req.user.id) {
|
||||
return next();
|
||||
}
|
||||
next(new common.errors.UnauthorizedError({
|
||||
message: common.i18n.t('errors.middleware.auth.accessDenied')
|
||||
}));
|
||||
};
|
||||
|
||||
const cookieCsrfProtection = (req, res, next) => {
|
||||
// If there is no origin on the session object it means this is a *new*
|
||||
// session, that hasn't been initialised yet. So we don't need CSRF protection
|
||||
if (!req.session.origin) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (req.session.origin !== getOrigin(req)) {
|
||||
return next(new common.errors.BadRequestError({
|
||||
message: common.i18n.t('errors.middleware.auth.mismatchedOrigin')
|
||||
}));
|
||||
}
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
module.exports = exports = {
|
||||
getSession,
|
||||
cookieCsrfProtection,
|
||||
safeGetSession: [getSession, cookieCsrfProtection],
|
||||
createSession,
|
||||
destroySession,
|
||||
getUser,
|
||||
ensureUser
|
||||
};
|
44
core/server/services/auth/session/store.js
Normal file
44
core/server/services/auth/session/store.js
Normal file
@ -0,0 +1,44 @@
|
||||
const {Store} = require('express-session');
|
||||
const common = require('../../../lib/common');
|
||||
|
||||
module.exports = class SessionStore extends Store {
|
||||
constructor(SessionModel) {
|
||||
super();
|
||||
this.SessionModel = SessionModel;
|
||||
}
|
||||
|
||||
destroy(sid, callback) {
|
||||
this.SessionModel
|
||||
.destroy({session_id: sid})
|
||||
.then(() => {
|
||||
callback(null);
|
||||
})
|
||||
.catch(callback);
|
||||
}
|
||||
|
||||
get(sid, callback) {
|
||||
this.SessionModel
|
||||
.findOne({session_id: sid})
|
||||
.then((model) => {
|
||||
if (!model) {
|
||||
return callback(null, null);
|
||||
}
|
||||
callback(null, model.get('session_data'));
|
||||
})
|
||||
.catch(callback);
|
||||
}
|
||||
|
||||
set(sid, sessionData, callback) {
|
||||
if (!sessionData.user_id) {
|
||||
return callback(new common.errors.InternalServerError({
|
||||
message: common.i18n.t('errors.middleware.auth.missingUserID')
|
||||
}));
|
||||
}
|
||||
this.SessionModel
|
||||
.upsert({session_data: sessionData}, {session_id: sid})
|
||||
.then(() => {
|
||||
callback(null);
|
||||
})
|
||||
.catch(callback);
|
||||
}
|
||||
};
|
@ -73,6 +73,9 @@
|
||||
"clientCredentialsNotProvided": "Client credentials were not provided",
|
||||
"clientCredentialsNotValid": "Client credentials were not valid",
|
||||
"forInformationRead": "For information on how to fix this, please read {url}.",
|
||||
"unknownOrigin": "Could not determine origin of request.",
|
||||
"mismatchedOrigin": "Request made from incorrect origin.",
|
||||
"missingUserIDForSession": "Cannot create session without user id.",
|
||||
"accessDenied": "Access denied.",
|
||||
"pleaseSignIn": "Please Sign In"
|
||||
},
|
||||
|
@ -1,22 +1,21 @@
|
||||
var should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
passport = require('passport'),
|
||||
rewire = require('rewire'),
|
||||
BearerStrategy = require('passport-http-bearer').Strategy,
|
||||
ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
|
||||
auth = rewire('../../../../server/services/auth'),
|
||||
common = require('../../../../server/lib/common'),
|
||||
user = {id: 1},
|
||||
info = {scope: '*'},
|
||||
token = 'test_token',
|
||||
testClient = 'test_client',
|
||||
testSecret = 'not_available',
|
||||
client = {
|
||||
id: 2,
|
||||
type: 'ua'
|
||||
},
|
||||
|
||||
sandbox = sinon.sandbox.create();
|
||||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
const passport = require('passport');
|
||||
const BearerStrategy = require('passport-http-bearer').Strategy;
|
||||
const ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy;
|
||||
const auth = require('../../../../server/services/auth');
|
||||
const common = require('../../../../server/lib/common');
|
||||
const models = require('../../../../server/models');
|
||||
const user = {id: 1};
|
||||
const info = {scope: '*'};
|
||||
const token = 'test_token';
|
||||
const testClient = 'test_client';
|
||||
const testSecret = 'not_available';
|
||||
const client = {
|
||||
id: 2,
|
||||
type: 'ua'
|
||||
};
|
||||
const sandbox = sinon.sandbox.create();
|
||||
|
||||
function registerSuccessfulBearerStrategy() {
|
||||
// register fake BearerStrategy which always authenticates
|
||||
@ -84,6 +83,10 @@ function registerFaultyClientPasswordStrategy() {
|
||||
describe('Auth', function () {
|
||||
var res, req, next, loggingStub;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
req = {};
|
||||
res = {};
|
||||
|
254
core/test/unit/services/auth/session/index_spec.js
Normal file
254
core/test/unit/services/auth/session/index_spec.js
Normal file
@ -0,0 +1,254 @@
|
||||
const sessionService = require('../../../../../server/services/auth/session');
|
||||
const SessionStore = require('../../../../../server/services/auth/session/store');
|
||||
const config = require('../../../../../server/config');
|
||||
const models = require('../../../../../server/models');
|
||||
const sinon = require('sinon');
|
||||
const should = require('should');
|
||||
const {
|
||||
BadRequestError,
|
||||
UnauthorizedError,
|
||||
InternalServerError
|
||||
} = require('../../../../../server/lib/common/errors');
|
||||
|
||||
describe('Session Service', function () {
|
||||
let sandbox;
|
||||
before(function () {
|
||||
models.init();
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
const fakeReq = function fakeReq() {
|
||||
return {
|
||||
session: {
|
||||
destroy() {}
|
||||
},
|
||||
body: {},
|
||||
get() {}
|
||||
};
|
||||
};
|
||||
|
||||
const fakeRes = function fakeRes() {
|
||||
return {
|
||||
sendStatus() {}
|
||||
};
|
||||
};
|
||||
|
||||
describe('createSession', function () {
|
||||
it('calls next with a BadRequestError if there is no Origin or Refferer', function (done) {
|
||||
const req = fakeReq();
|
||||
sandbox.stub(req, 'get')
|
||||
.withArgs('origin').returns('')
|
||||
.withArgs('referrer').returns('');
|
||||
|
||||
sessionService.createSession(req, fakeRes(), function next(err) {
|
||||
should.equal(err instanceof BadRequestError, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets req.session.user_id,origin,user_agent,ip and calls sendStatus with 201 if the check succeeds', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
|
||||
sandbox.stub(req, 'get')
|
||||
.withArgs('origin').returns('http://host.tld')
|
||||
.withArgs('user-agent').returns('bububang');
|
||||
|
||||
req.ip = '127.0.0.1';
|
||||
req.user = models.User.forge({id: 23});
|
||||
|
||||
sandbox.stub(res, 'sendStatus')
|
||||
.callsFake(function (statusCode) {
|
||||
should.equal(req.session.user_id, 23);
|
||||
should.equal(req.session.origin, 'http://host.tld');
|
||||
should.equal(req.session.user_agent, 'bububang');
|
||||
should.equal(req.session.ip, '127.0.0.1');
|
||||
should.equal(statusCode, 201);
|
||||
done();
|
||||
});
|
||||
|
||||
sessionService.createSession(req, res);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroySession', function () {
|
||||
it('calls req.session.destroy', function () {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
const destroyStub = sandbox.stub(req.session, 'destroy');
|
||||
|
||||
sessionService.destroySession(req, res);
|
||||
|
||||
should.equal(destroyStub.callCount, 1);
|
||||
});
|
||||
|
||||
it('calls next with InternalServerError if destroy errors', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(req.session, 'destroy')
|
||||
.callsFake(function (fn) {
|
||||
fn(new Error('oops'));
|
||||
});
|
||||
|
||||
sessionService.destroySession(req, res, function next(err) {
|
||||
should.equal(err instanceof InternalServerError, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls sendStatus with 204 if destroy does not error', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(req.session, 'destroy')
|
||||
.callsFake(function (fn) {
|
||||
fn();
|
||||
});
|
||||
sandbox.stub(res, 'sendStatus')
|
||||
.callsFake(function (status) {
|
||||
should.equal(status, 204);
|
||||
done();
|
||||
});
|
||||
|
||||
sessionService.destroySession(req, res);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUser', function () {
|
||||
it('sets req.user to null and calls next if there is no session', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
|
||||
delete req.session;
|
||||
|
||||
sessionService.getUser(req, res, function next() {
|
||||
should.equal(req.user, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets req.user to null and calls next if there is no session', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
|
||||
sessionService.getUser(req, res, function next() {
|
||||
should.equal(req.user, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls User.findOne with id set to req.session.user_id', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(models.User, 'findOne')
|
||||
.callsFake(function (opts) {
|
||||
should.equal(opts.id, 23);
|
||||
done();
|
||||
});
|
||||
|
||||
req.session.user_id = 23;
|
||||
sessionService.getUser(req, res);
|
||||
});
|
||||
|
||||
it('sets req.user to null and calls next if the user is not found', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(models.User, 'findOne')
|
||||
.rejects();
|
||||
|
||||
req.session.user_id = 23;
|
||||
sessionService.getUser(req, res, function next() {
|
||||
should.equal(req.user, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls next after settign req.user to the found user', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
const user = models.User.forge({id: 23});
|
||||
sandbox.stub(models.User, 'findOne')
|
||||
.resolves(user);
|
||||
|
||||
req.session.user_id = 23;
|
||||
sessionService.getUser(req, res, function next() {
|
||||
should.equal(req.user, user);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ensureUser', function () {
|
||||
it('calls next with no error if req.user.id exists', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
const user = models.User.forge({id: 23});
|
||||
req.user = user;
|
||||
|
||||
sessionService.ensureUser(req, res, function next(err) {
|
||||
should.equal(err, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls next with UnauthorizedError if req.user.id does not exist', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
|
||||
sessionService.ensureUser(req, res, function next(err) {
|
||||
should.equal(err instanceof UnauthorizedError, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('CSRF protection', function () {
|
||||
it('calls next if the session is uninitialized', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
|
||||
sessionService.cookieCsrfProtection(req, res, function next(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls next if req origin matches the session origin', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(req, 'get')
|
||||
.withArgs('origin').returns('http://host.tld');
|
||||
req.session.origin = 'http://host.tld';
|
||||
|
||||
sessionService.cookieCsrfProtection(req, res, function next(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls next with BadRequestError if the origin of req does not match the session', function (done) {
|
||||
const req = fakeReq();
|
||||
const res = fakeRes();
|
||||
sandbox.stub(req, 'get')
|
||||
.withArgs('origin').returns('http://host.tld');
|
||||
req.session.origin = 'http://different-host.tld';
|
||||
|
||||
sessionService.cookieCsrfProtection(req, res, function next(err) {
|
||||
should.equal(err instanceof BadRequestError, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('safeGetSession', function () {
|
||||
it('is an array of getSession and cookieCsrfProtection', function () {
|
||||
should.deepEqual(sessionService.safeGetSession, [
|
||||
sessionService.getSession,
|
||||
sessionService.cookieCsrfProtection
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
185
core/test/unit/services/auth/session/store_spec.js
Normal file
185
core/test/unit/services/auth/session/store_spec.js
Normal file
@ -0,0 +1,185 @@
|
||||
const SessionStore = require('../../../../../server/services/auth/session/store');
|
||||
const models = require('../../../../../server/models');
|
||||
const EventEmitter = require('events');
|
||||
const {Store} = require('express-session');
|
||||
const sinon = require('sinon');
|
||||
const should = require('should');
|
||||
|
||||
describe('Auth Service SessionStore', function () {
|
||||
let sandbox;
|
||||
before(function () {
|
||||
models.init();
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe('inheritance', function () {
|
||||
it('Is an instance of EventEmitter', function () {
|
||||
const store = new SessionStore();
|
||||
should.equal(store instanceof EventEmitter, true);
|
||||
});
|
||||
|
||||
it('Is an instance of Store', function () {
|
||||
const store = new SessionStore();
|
||||
should.equal(store instanceof Store, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SessionStore#destroy', function () {
|
||||
it('calls destroy on the model with the session_id `sid`', function (done) {
|
||||
const destroyStub = sandbox.stub(models.Session, 'destroy')
|
||||
.resolves();
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.destroy(sid, function () {
|
||||
const destroyStubCall = destroyStub.getCall(0);
|
||||
should.equal(destroyStubCall.args[0].session_id, sid);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with null if destroy resolve', function (done) {
|
||||
sandbox.stub(models.Session, 'destroy')
|
||||
.resolves();
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.destroy(sid, function (err) {
|
||||
should.equal(err, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with the error if destroy errors', function (done) {
|
||||
const error = new Error('beam me up scotty');
|
||||
sandbox.stub(models.Session, 'destroy')
|
||||
.rejects(error);
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.destroy(sid, function (err) {
|
||||
should.equal(err, error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('SessionStore#get', function () {
|
||||
it('calls findOne on the model with the session_id `sid`', function (done) {
|
||||
const findOneStub = sandbox.stub(models.Session, 'findOne')
|
||||
.resolves();
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.get(sid, function () {
|
||||
const findOneStubCall = findOneStub.getCall(0);
|
||||
should.equal(findOneStubCall.args[0].session_id, sid);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('callsback with null, null if findOne does not return a model', function (done) {
|
||||
sandbox.stub(models.Session, 'findOne')
|
||||
.resolves(null);
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.get(sid, function (err, session) {
|
||||
should.equal(err, null);
|
||||
should.equal(session, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('callsback with null, model.session_data if findOne does return a model', function (done) {
|
||||
const model = models.Session.forge({
|
||||
session_data: {
|
||||
ice: 'cube'
|
||||
}
|
||||
});
|
||||
sandbox.stub(models.Session, 'findOne')
|
||||
.resolves(model);
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.get(sid, function (err, session) {
|
||||
should.equal(err, null);
|
||||
should.deepEqual(session, {
|
||||
ice: 'cube'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('callsback with an error if the findOne does error', function (done) {
|
||||
const error = new Error('hot damn');
|
||||
sandbox.stub(models.Session, 'findOne')
|
||||
.rejects(error);
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
store.get(sid, function (err) {
|
||||
should.equal(err, error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('SessionStore#set', function () {
|
||||
it('calls back with an error if there is no user_id on the session_data', function (done) {
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
const session_data = {};
|
||||
store.set(sid, session_data, function (err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls upsert on the model with the session_id and the session_data', function (done) {
|
||||
const upsertStub = sandbox.stub(models.Session, 'upsert')
|
||||
.resolves();
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
const session_data = {user_id: 100};
|
||||
store.set(sid, session_data, function () {
|
||||
const upsertStubCall = upsertStub.getCall(0);
|
||||
should.equal(upsertStubCall.args[0].session_data, session_data);
|
||||
should.equal(upsertStubCall.args[1].session_id, sid);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with an error if upsert errors', function (done) {
|
||||
const error = new Error('huuuuuurrr');
|
||||
sandbox.stub(models.Session, 'upsert')
|
||||
.rejects(error);
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
const session_data = {user_id: 100};
|
||||
store.set(sid, session_data, function (err) {
|
||||
should.equal(err, error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with null, null if upsert succeed', function (done) {
|
||||
sandbox.stub(models.Session, 'upsert')
|
||||
.resolves('success');
|
||||
|
||||
const store = new SessionStore(models.Session);
|
||||
const sid = 1;
|
||||
const session_data = {user_id: 100};
|
||||
store.set(sid, session_data, function (err, data) {
|
||||
should.equal(err, null);
|
||||
should.equal(data, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -52,6 +52,7 @@
|
||||
"express-brute": "1.0.1",
|
||||
"express-hbs": "1.0.4",
|
||||
"express-query-boolean": "2.0.0",
|
||||
"express-session": "1.15.6",
|
||||
"extract-zip": "1.6.7",
|
||||
"fs-extra": "3.0.1",
|
||||
"ghost-gql": "0.0.10",
|
||||
|
28
yarn.lock
28
yarn.lock
@ -1157,6 +1157,10 @@ crc32-stream@^2.0.0:
|
||||
crc "^3.4.4"
|
||||
readable-stream "^2.0.0"
|
||||
|
||||
crc@3.4.4:
|
||||
version "3.4.4"
|
||||
resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b"
|
||||
|
||||
crc@^3.4.4:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/crc/-/crc-3.5.0.tgz#98b8ba7d489665ba3979f59b21381374101a1964"
|
||||
@ -1790,6 +1794,20 @@ express-query-boolean@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/express-query-boolean/-/express-query-boolean-2.0.0.tgz#ea56ac8138e2b95b171b8eee2af88738302941c3"
|
||||
|
||||
express-session@1.15.6:
|
||||
version "1.15.6"
|
||||
resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.6.tgz#47b4160c88f42ab70fe8a508e31cbff76757ab0a"
|
||||
dependencies:
|
||||
cookie "0.3.1"
|
||||
cookie-signature "1.0.6"
|
||||
crc "3.4.4"
|
||||
debug "2.6.9"
|
||||
depd "~1.1.1"
|
||||
on-headers "~1.0.1"
|
||||
parseurl "~1.3.2"
|
||||
uid-safe "~2.1.5"
|
||||
utils-merge "1.0.1"
|
||||
|
||||
express@4.16.3, express@^4.16.2:
|
||||
version "4.16.3"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
|
||||
@ -5025,6 +5043,10 @@ rai@~0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/rai/-/rai-0.1.12.tgz#8ccfd014d0f9608630dd73c19b8e4b057754a6a6"
|
||||
|
||||
random-bytes@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b"
|
||||
|
||||
range-parser@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
|
||||
@ -6173,6 +6195,12 @@ uglify-to-browserify@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
|
||||
|
||||
uid-safe@~2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
|
||||
dependencies:
|
||||
random-bytes "~1.0.0"
|
||||
|
||||
uid2@0.0.x:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82"
|
||||
|
Loading…
Reference in New Issue
Block a user