diff --git a/src/oidc.js b/src/oidc.js index a805c488d..2beb44323 100644 --- a/src/oidc.js +++ b/src/oidc.js @@ -710,6 +710,13 @@ async function start() { jwksKeys.push(JSON.parse(keyRs256)); } + let cookieSecret = await settings.getCookieSecret(); + if (!cookieSecret) { + debug('Generating new cookie secret'); + cookieSecret = require('crypto').randomBytes(256).toString('base64'); + await settings.setCookieSecret(cookieSecret); + } + const configuration = { findAccount, renderError, @@ -740,8 +747,7 @@ async function start() { allowOmittingSingleRegisteredRedirectUri: true, clients: [], cookies: { - // FIXME https://github.com/panva/node-oidc-provider/blob/b1c1a9318036c2d3793cc9e668f99937c5c36bc6/lib/helpers/defaults.js#L770 - keys: [ 'cookiesecret1', 'cookiesecret2' ] + keys: [ cookieSecret ] }, pkce: { required: function pkceRequired(/*ctx, client*/) { diff --git a/src/settings.js b/src/settings.js index 94d6672e1..7123c7710 100644 --- a/src/settings.js +++ b/src/settings.js @@ -7,6 +7,9 @@ exports = module.exports = { getTimeZone, setTimeZone, + getCookieSecret, + setCookieSecret, + getCloudronName, setCloudronName, @@ -119,6 +122,7 @@ exports = module.exports = { // strings AUTOUPDATE_PATTERN_KEY: 'autoupdate_pattern', TIME_ZONE_KEY: 'time_zone', + CLOUDRON_COOKIE_SECRET_KEY: 'cookie_secret', CLOUDRON_NAME_KEY: 'cloudron_name', LANGUAGE_KEY: 'language', CLOUDRON_ID_KEY: 'cloudron_id', @@ -175,6 +179,7 @@ const gDefaults = (function () { const result = { }; result[exports.AUTOUPDATE_PATTERN_KEY] = cron.DEFAULT_AUTOUPDATE_PATTERN; result[exports.TIME_ZONE_KEY] = 'UTC'; + result[exports.CLOUDRON_COOKIE_SECRET_KEY] = ''; result[exports.CLOUDRON_NAME_KEY] = 'Cloudron'; result[exports.DYNAMIC_DNS_KEY] = false; result[exports.IPV6_CONFIG_KEY] = { @@ -332,6 +337,19 @@ async function getTimeZone() { return tz; } +async function getCookieSecret() { + const secret = await get(exports.CLOUDRON_COOKIE_SECRET_KEY); + return secret; +} + +async function setCookieSecret(secret) { + assert.strictEqual(typeof secret, 'string'); + + if (!secret) throw new BoxError(BoxError.BAD_FIELD, 'secret is empty'); + + await set(exports.CLOUDRON_COOKIE_SECRET_KEY, secret); +} + async function getCloudronName() { const name = await get(exports.CLOUDRON_NAME_KEY); if (name === null) return gDefaults[exports.CLOUDRON_NAME_KEY];