From 0a627ef9971cf98c8e9001436d158552015a25eb Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 11 Sep 2019 11:49:35 +1000 Subject: [PATCH] Add cookieMaxAge and secureCookies options (#1612) --- .changeset/smooth-pumpkins-deliver/changes.json | 7 +++++++ .changeset/smooth-pumpkins-deliver/changes.md | 13 +++++++++++++ packages/keystone/lib/Keystone/index.js | 14 ++++++++++++-- packages/session/lib/session.js | 9 ++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 .changeset/smooth-pumpkins-deliver/changes.json create mode 100644 .changeset/smooth-pumpkins-deliver/changes.md diff --git a/.changeset/smooth-pumpkins-deliver/changes.json b/.changeset/smooth-pumpkins-deliver/changes.json new file mode 100644 index 00000000000..4e6257633fd --- /dev/null +++ b/.changeset/smooth-pumpkins-deliver/changes.json @@ -0,0 +1,7 @@ +{ + "releases": [ + { "name": "@keystone-alpha/keystone", "type": "minor" }, + { "name": "@keystone-alpha/session", "type": "major" } + ], + "dependents": [] +} diff --git a/.changeset/smooth-pumpkins-deliver/changes.md b/.changeset/smooth-pumpkins-deliver/changes.md new file mode 100644 index 00000000000..8c815504991 --- /dev/null +++ b/.changeset/smooth-pumpkins-deliver/changes.md @@ -0,0 +1,13 @@ +Adds a `cookieMaxAge` and `secureCookies` option to the keystone constructor. + +These will default to 30 days for `cookieMaxAge` and `true` in production `false` in other environments for `secureCookies`. + +### Usage +```javascript +const keystone = new Keystone({ + cookieMaxAge: 1000 * 60 * 60 * 24 * 7, // 1 week + secureCookies: true, +}); +``` + +Note: `commonSessionMiddleware` now accepts a config object rather than multiple arguments. \ No newline at end of file diff --git a/packages/keystone/lib/Keystone/index.js b/packages/keystone/lib/Keystone/index.js index a8d1138caaa..711a9c22e24 100644 --- a/packages/keystone/lib/Keystone/index.js +++ b/packages/keystone/lib/Keystone/index.js @@ -44,6 +44,8 @@ module.exports = class Keystone { onConnect, cookieSecret = 'qwerty', sessionStore, + secureCookies = process.env.NODE_ENV === 'production', // Default to true in production + cookieMaxAge = 1000 * 60 * 60 * 24 * 30, // 30 days schemaNames = ['public'], }) { this.name = name; @@ -58,9 +60,11 @@ module.exports = class Keystone { this._extendedMutations = []; this._graphQLQuery = {}; this._cookieSecret = cookieSecret; + this._secureCookies = secureCookies; + this._cookieMaxAge = cookieMaxAge; this._sessionStore = sessionStore; - this.registeredTypes = new Set(); this.eventHandlers = { onConnect }; + this.registeredTypes = new Set(); this._schemaNames = schemaNames; if (adapters) { @@ -544,7 +548,13 @@ module.exports = class Keystone { // Used by other middlewares such as authentication strategies. Important // to be first so the methods added to `req` are available further down // the request pipeline. - commonSessionMiddleware(this, this._cookieSecret, this._sessionStore), + commonSessionMiddleware({ + keystone: this, + cookieSecret: this._cookieSecret, + sessionStore: this.sessionStore, + secureCookies: this._secureCookies, + cookieMaxAge: this._cookieMaxAge, + }), ...(await Promise.all( [ // Inject any field middlewares (eg; WYSIWIG's static assets) diff --git a/packages/session/lib/session.js b/packages/session/lib/session.js index 9c06776bd6b..93ffa273f68 100644 --- a/packages/session/lib/session.js +++ b/packages/session/lib/session.js @@ -2,7 +2,13 @@ const cookieSignature = require('cookie-signature'); const expressSession = require('express-session'); const cookie = require('cookie'); -const commonSessionMiddleware = (keystone, cookieSecret, sessionStore) => { +const commonSessionMiddleware = ({ + keystone, + cookieSecret, + sessionStore, + secureCookies, + cookieMaxAge, +}) => { const COOKIE_NAME = 'keystone.sid'; // We have at least one auth strategy @@ -50,6 +56,7 @@ const commonSessionMiddleware = (keystone, cookieSecret, sessionStore) => { resave: false, saveUninitialized: false, name: COOKIE_NAME, + cookie: { secure: secureCookies, maxAge: cookieMaxAge }, store: sessionStore, });