Skip to content

Commit

Permalink
adopt standard
Browse files Browse the repository at this point in the history
  • Loading branch information
SerayaEryn committed Nov 18, 2018
1 parent 5188eeb commit 2a04ae5
Show file tree
Hide file tree
Showing 14 changed files with 661 additions and 678 deletions.
38 changes: 0 additions & 38 deletions .eslintrc.yaml

This file was deleted.

1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![Build Status](https://travis-ci.org/SerayaEryn/fastify-session.svg?branch=master)](https://travis-ci.org/SerayaEryn/fastify-session)
[![Coverage Status](https://coveralls.io/repos/github/SerayaEryn/fastify-session/badge.svg?branch=master)](https://coveralls.io/github/SerayaEryn/fastify-session?branch=master)
[![NPM version](https://img.shields.io/npm/v/fastify-session.svg?style=flat)](https://www.npmjs.com/package/fastify-session)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)

A session plugin for [fastify](http://fastify.io/).
Requires the [fastify-cookie](https://github.com/fastify/fastify-cookie) plugin.
Expand Down
178 changes: 89 additions & 89 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,160 +1,160 @@
'use strict';

const fastifyPlugin = require('fastify-plugin');
const uid = require('uid-safe').sync;
const cookieSignature = require('cookie-signature');
const Store = require('./lib/store');
const Session = require('./lib/session');
const metadata = require('./lib/metadata');

function session(fastify, opts, next) {
fastify.addHook('preHandler', handleSession);
fastify.addHook('onSend', saveSession);

const store = opts.store || new Store();
fastify.decorateRequest('sessionStore', store);
fastify.decorateRequest('session', {});
const cookieName = opts.cookieName || 'sessionId';
const secret = opts.secret;
const cookieOpts = opts.cookie || {};
cookieOpts.secure = option(cookieOpts, 'secure', true);
const saveUninitialized = option(opts, 'saveUninitialized', true);
'use strict'

const fastifyPlugin = require('fastify-plugin')
const uid = require('uid-safe').sync
const cookieSignature = require('cookie-signature')
const Store = require('./lib/store')
const Session = require('./lib/session')
const metadata = require('./lib/metadata')

function session (fastify, opts, next) {
fastify.addHook('preHandler', handleSession)
fastify.addHook('onSend', saveSession)

const store = opts.store || new Store()
fastify.decorateRequest('sessionStore', store)
fastify.decorateRequest('session', {})
const cookieName = opts.cookieName || 'sessionId'
const secret = opts.secret
const cookieOpts = opts.cookie || {}
cookieOpts.secure = option(cookieOpts, 'secure', true)
const saveUninitialized = option(opts, 'saveUninitialized', false)

if (!secret) {
next(new Error('the secret option is required!'));
return;
next(new Error('the secret option is required!'))
return
}

if (secret.length < 32) {
next(new Error('the secret must have length 32 or greater'));
next(new Error('the secret must have length 32 or greater'))
}

function handleSession(request, reply, done) {
const url = request.req.url;
function handleSession (request, reply, done) {
const url = request.req.url
if (url.indexOf(cookieOpts.path || '/') !== 0) {
done();
return;
done()
return
}
let sessionId = request.cookies[cookieName];
let sessionId = request.cookies[cookieName]
if (!sessionId) {
newSession(secret, request, reply, done);
newSession(secret, request, reply, done)
} else {
const decryptedSessionId = cookieSignature.unsign(sessionId, secret);
const decryptedSessionId = cookieSignature.unsign(sessionId, secret)
if (decryptedSessionId === false) {
newSession(secret, request, reply, done);
newSession(secret, request, reply, done)
} else {
store.get(decryptedSessionId, (err, session) => {
if (err) {
if (err.code === 'ENOENT') {
newSession(secret, request, reply, done);
newSession(secret, request, reply, done)
} else {
done(err);
done(err)
}
return;
return
}
if(!session) {
newSession(secret, request, reply, done);
return;
if (!session) {
newSession(secret, request, reply, done)
return
}
if (session && session.expires && session.expires <= Date.now()) {
store.destroy(sessionId, getDestroyCallback(secret, request, reply, done));
return;
store.destroy(sessionId, getDestroyCallback(secret, request, reply, done))
return
}
if (cookieOpts.maxAge) {
session.expires = Date.now() + cookieOpts.maxAge;
session.expires = Date.now() + cookieOpts.maxAge
}
request.session = session;
done();
});
request.session = session
done()
})
}
}
}

function getDestroyCallback(secret, request, reply, done) {
return function destroyCallback(err) {
function getDestroyCallback (secret, request, reply, done) {
return function destroyCallback (err) {
if (err) {
done(err);
return;
done(err)
return
}
newSession(secret, request, reply, done);
newSession(secret, request, reply, done)
}
}

function newSession(secret, request, reply, done) {
const sessionId = uid(24);
const encryptedSessionId = cookieSignature.sign(sessionId, secret);
let expires = null;
const sessionId = uid(24)
const encryptedSessionId = cookieSignature.sign(sessionId, secret)
let expires = null
if (cookieOpts.maxAge) {
expires = Date.now() + cookieOpts.maxAge;
expires = Date.now() + cookieOpts.maxAge
}
const session = new Session(sessionId, encryptedSessionId, expires, cookieOpts);
request.session = session;
done();
const session = new Session(sessionId, encryptedSessionId, expires, cookieOpts)
request.session = session
done()
}

function saveSession(request, reply, payload, done) {
const session = request.session;
function saveSession (request, reply, payload, done) {
const session = request.session
if (!session || !session.sessionId || !shouldSaveSession(request, cookieOpts)) {
done();
return;
done()
return
}
store.set(session.sessionId, session, (err) => {
if (err) {
done(err);
return;
done(err)
return
}
const cookieOptions = getCookieOptions();
reply.setCookie(cookieName, session.encryptedSessionId, cookieOptions);
done();
});
const cookieOptions = getCookieOptions()
reply.setCookie(cookieName, session.encryptedSessionId, cookieOptions)
done()
})
}

function getCookieOptions() {
function getCookieOptions () {
return {
path: cookieOpts.path || '/',
httpOnly: cookieOpts.httpOnly !== undefined ? cookieOpts.httpOnly : true,
secure: cookieOpts.secure,
expires: getExpires(cookieOpts),
sameSite: cookieOpts.sameSite || null,
domain: cookieOpts.domain || null
};
}
}

function shouldSaveSession(request, cookieOpts) {
if(!saveUninitialized && !isSessionModified(request.session)) {
return false;
function shouldSaveSession (request, cookieOpts) {
if (!saveUninitialized && !isSessionModified(request.session)) {
return false
}
if (cookieOpts.secure !== true) {
return true;
return true
}
const connection = request.req.connection;
const connection = request.req.connection
if (connection && connection.encrypted === true) {
return true;
return true
}
const forwardedProto = request.headers['x-forwarded-proto'];
return forwardedProto === 'https';
const forwardedProto = request.headers['x-forwarded-proto']
return forwardedProto === 'https'
}

function isSessionModified(session) {
return (Object.keys(session).length !== 4);
function isSessionModified (session) {
return (Object.keys(session).length !== 4)
}

next();
next()
}

function getExpires(cookieOpts) {
let expires = null;
function getExpires (cookieOpts) {
let expires = null
if (cookieOpts.expires) {
expires = cookieOpts.expires;
} else if(cookieOpts.maxAge) {
expires = new Date(Date.now() + cookieOpts.maxAge);
expires = cookieOpts.expires
} else if (cookieOpts.maxAge) {
expires = new Date(Date.now() + cookieOpts.maxAge)
}
return expires;
return expires
}

function option(options, key, def) {
return options[key] === undefined ? def : options[key];
function option (options, key, def) {
return options[key] === undefined ? def : options[key]
}

exports = module.exports = fastifyPlugin(session, metadata);
module.exports.Store = Store;
exports = module.exports = fastifyPlugin(session, metadata)
module.exports.Store = Store
12 changes: 6 additions & 6 deletions lib/cookie.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';
'use strict'

module.exports = class Cookie {
constructor(cookieOpts) {
this.path = '/';
this.maxAge = null;
this.httpOnly = true;
Object.assign(this, cookieOpts);
constructor (cookieOpts) {
this.path = '/'
this.maxAge = null
this.httpOnly = true
Object.assign(this, cookieOpts)
}
}
4 changes: 2 additions & 2 deletions lib/metadata.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use strict';
'use strict'

module.exports = {
fastify: '>=1.0.0',
name: 'fastify-session',
dependencies: [
'fastify-cookie'
]
};
}
14 changes: 7 additions & 7 deletions lib/session.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use strict';
'use strict'

const Cookie = require('./cookie');
const Cookie = require('./cookie')

module.exports = class Session {
constructor(sessionId, encryptedSessionId, expires, cookieOpts) {
this.sessionId = sessionId;
this.encryptedSessionId = encryptedSessionId;
this.expires = expires;
this.cookie = new Cookie(cookieOpts);
constructor (sessionId, encryptedSessionId, expires, cookieOpts) {
this.sessionId = sessionId
this.encryptedSessionId = encryptedSessionId
this.expires = expires
this.cookie = new Cookie(cookieOpts)
}
}
30 changes: 15 additions & 15 deletions lib/store.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
'use strict';
'use strict'

var EventEmitter = require('events').EventEmitter;
var util = require('util');
var EventEmitter = require('events').EventEmitter
var util = require('util')

function Store() {
this.store = {};
EventEmitter.call(this);
function Store () {
this.store = {}
EventEmitter.call(this)
}

util.inherits(Store, EventEmitter);
util.inherits(Store, EventEmitter)

Store.prototype.set = function set(sessionId, session, callback) {
this.store[sessionId] = session;
callback();
Store.prototype.set = function set (sessionId, session, callback) {
this.store[sessionId] = session
callback()
}

Store.prototype.get = function get(sessionId, callback) {
const session = this.store[sessionId];
callback(null, session);
Store.prototype.get = function get (sessionId, callback) {
const session = this.store[sessionId]
callback(null, session)
}

Store.prototype.destroy = function destroy(sessionId, callback) {
this.store[sessionId] = undefined;
Store.prototype.destroy = function destroy (sessionId, callback) {
this.store[sessionId] = undefined
callback()
}

Expand Down
Loading

0 comments on commit 2a04ae5

Please sign in to comment.