Skip to content

Commit

Permalink
Merge pull request #1658 from alphagov/ldeb-session-store
Browse files Browse the repository at this point in the history
Use file store for session data
  • Loading branch information
lfdebrux committed Oct 10, 2022
2 parents 6b01293 + 3b89c44 commit bf4474e
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 122 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
## Unreleased

### Breaking changes
- [#1648: Change default session store to cookie store when in production mode](https://github.com/alphagov/govuk-prototype-kit/pull/1648) When hosted online the kit will now preserve user session data between server restarts by default.
- [#1658: Use file store for session data](https://github.com/alphagov/govuk-prototype-kit/pull/1658)
- When running locally the kit will now preserve user session data between restarts
- Option `useCookieSessionStore` is no longer supported
- [#1638: Make serve default command](https://github.com/alphagov/govuk-prototype-kit/pull/1638)
- Running `npm start` after creating starter prototype will now run 'production' command
- Users now need to run `npm run dev` when they want to start their prototype on their local machine
Expand Down
9 changes: 4 additions & 5 deletions lib/build/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ const extensions = require('../extensions/extensions')
const utils = require('../utils')

const buildConfig = require('./config.json')
const { projectDir, packageDir } = require('../path-utils')
const { projectDir, packageDir, tempDir } = require('../path-utils')
const { paths } = buildConfig

const appSassPath = path.join(projectDir, paths.assets, 'sass')
const shadowNunjucks = path.join(projectDir, paths.shadowNunjucks)
const libAssetsPath = path.join(packageDir, paths.libAssets)
const libSassPath = path.join(libAssetsPath, 'sass')
const tempPath = path.join(projectDir, '.tmp')
const tempSassPath = path.join(tempPath, 'sass')
const tempSassPath = path.join(tempDir, 'sass')

const appCssPath = path.join(paths.public, 'stylesheets')

Expand Down Expand Up @@ -62,9 +61,9 @@ function clean () {
del.sync(['public/**', '.port.tmp'])
}

function ensureTempDirExists (dir = tempPath) {
function ensureTempDirExists (dir = tempDir) {
fse.ensureDirSync(dir, { recursive: true })
fse.writeFileSync(path.join(tempPath, '.gitignore'), '*')
fse.writeFileSync(path.join(tempDir, '.gitignore'), '*')
}

function sassExtensions () {
Expand Down
1 change: 0 additions & 1 deletion lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ const getConfig = () => {
overrideOrDefault('port', 'PORT', asNumber, 3000)
overrideOrDefault('useBrowserSync', 'USE_BROWSER_SYNC', asBoolean, true)
overrideOrDefault('useAutoStoreData', 'USE_AUTO_STORE_DATA', asBoolean, true)
overrideOrDefault('useCookieSessionStore', 'USE_COOKIE_SESSION_STORE', asBoolean, config.isProduction)

if (config.serviceName === undefined) {
config.serviceName = 'GOV.UK Prototype Kit'
Expand Down
10 changes: 0 additions & 10 deletions lib/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ describe('config', () => {
useHttps: true,
useAutoStoreData: true,
useBrowserSync: true,
useCookieSessionStore: false,
isProduction: false,
isDevelopment: false,
onGlitch: false
Expand Down Expand Up @@ -88,15 +87,6 @@ describe('config', () => {
}))
})

it('defaults to using cookie session store when in production', () => {
process.env.NODE_ENV = 'production'

expect(config.getConfig()).toStrictEqual(mergeWithDefaults({
isProduction: true,
useCookieSessionStore: true
}))
})

it('allows the user to set some values in config and others in environment variables', () => {
testScope.configJs = {
serviceName: 'Another Test Service'
Expand Down
3 changes: 2 additions & 1 deletion lib/path-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const path = require('path')

// Directory locations
const path = require('path')
exports.packageDir = path.resolve(__dirname, '..')
exports.projectDir = process.cwd()
exports.appDir = path.join(exports.projectDir, 'app')
exports.tempDir = path.join(exports.projectDir, '.tmp')
40 changes: 22 additions & 18 deletions lib/sessionUtils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const { getConfig } = require('./config')
const sessionInCookie = require('client-sessions')
const sessionInMemory = require('express-session')
const path = require('path')
const { projectDir } = require('./path-utils')

const session = require('express-session')
const FileStore = require('session-file-store')(session)
const { get: getKeypath } = require('lodash')

const { getConfig } = require('./config')
const { projectDir, tempDir } = require('./path-utils')

// Add Nunjucks function called 'checked' to populate radios and checkboxes
const addCheckedFunction = function (env) {
env.addGlobal('checked', function (name, value) {
Expand Down Expand Up @@ -115,8 +117,10 @@ const getSessionNameFromServiceName = (serviceName) => {
}

const getSessionMiddleware = () => {
const config = getConfig()

// Session uses service name to avoid clashes with other prototypes
const sessionName = getSessionNameFromServiceName(getConfig().serviceName)
const sessionName = getSessionNameFromServiceName(config.serviceName)
const sessionHours = 4
const sessionOptions = {
secret: sessionName,
Expand All @@ -126,20 +130,20 @@ const getSessionMiddleware = () => {
}
}

// Support session data in cookie or memory
if (getConfig().useCookieSessionStore) {
return sessionInCookie(Object.assign(sessionOptions, {
cookieName: sessionName,
proxy: true,
requestKey: 'session'
}))
} else {
return sessionInMemory(Object.assign(sessionOptions, {
name: sessionName,
resave: false,
saveUninitialized: false
}))
const fileStoreOptions = {
path: path.join(tempDir, 'sessions')
}

if (config.isProduction) {
fileStoreOptions.secret = sessionName
}

return session(Object.assign(sessionOptions, {
name: sessionName,
resave: false,
saveUninitialized: false,
store: new FileStore(fileStoreOptions)
}))
}

module.exports = {
Expand Down
Loading

0 comments on commit bf4474e

Please sign in to comment.