Ghost/ghost/members-ssr/index.js

124 lines
3.4 KiB
JavaScript
Raw Normal View History

2019-04-05 09:57:14 +03:00
const concat = require('concat-stream');
const Cookies = require('cookies');
const ignition = require('ghost-ignition');
const {
BadRequestError
} = ignition.errors;
const EMPTY = {};
const SIX_MONTHS_MS = 1000 * 60 * 60 * 24 * 184;
const withCookies = (fn, cookieConfig) => (req, res) => {
return new Promise((resolve) => {
const cookies = new Cookies(req, res, cookieConfig);
resolve(fn(req, res, {cookies}));
});
};
const withBodyAndCookies = (fn, cookieConfig) => (req, res) => {
2019-04-05 09:57:14 +03:00
return new Promise((resolve, reject) => {
const cookies = new Cookies(req, res, cookieConfig);
req.on('error', reject);
req.pipe(concat(function (buff) {
const body = buff.toString();
resolve(fn(req, res, {body, cookies}));
}));
});
};
const get = (value) => {
return typeof value === 'function' ? value() : value;
};
2019-04-05 09:57:14 +03:00
module.exports = function create(options = EMPTY) {
if (options === EMPTY) {
throw new Error('Must pass options');
}
const {
cookieMaxAge = SIX_MONTHS_MS,
cookieSecure = true,
cookieName = 'members-ssr',
cookiePath = '/',
cookieKeys,
membersApi
} = options;
if (!membersApi) {
throw new Error('Missing option membersApi');
}
if (!cookieKeys) {
throw new Error('Missing option cookieKeys');
}
const cookieConfig = {
keys: [].concat(cookieKeys),
secure: cookieSecure
};
const getMemberDataFromToken = token => get(membersApi).getMemberDataFromMagicLinkToken(token);
2019-04-05 09:57:14 +03:00
const exchangeTokenForSession = withBodyAndCookies(async (_req, _res, {body, cookies}) => {
2019-04-05 09:57:14 +03:00
const token = body;
if (!body || typeof body !== 'string') {
return Promise.reject(new BadRequestError({
2019-04-05 09:57:14 +03:00
message: 'Expected body containing JWT'
}));
2019-04-05 09:57:14 +03:00
}
const member = await getMemberDataFromToken(token);
cookies.set(cookieName, member.email, {
signed: true,
httpOnly: true,
sameSite: 'lax',
maxAge: cookieMaxAge,
path: cookiePath
2019-04-05 09:57:14 +03:00
});
}, cookieConfig);
const deleteSession = withCookies((_req, _res, {cookies}) => {
cookies.set(cookieName, {
signed: true,
httpOnly: true,
sameSite: 'lax',
maxAge: cookieMaxAge,
path: cookiePath
});
}, cookieConfig);
const getMemberDataFromSession = withCookies(async (_req, _res, {cookies}) => {
try {
const email = cookies.get(cookieName, {
signed: true
});
return get(membersApi).getMemberIdentityData(email);
} catch (e) {
throw new BadRequestError({
2019-04-05 09:57:14 +03:00
message: `Cookie ${cookieName} not found`
});
2019-04-05 09:57:14 +03:00
}
}, cookieConfig);
const getIdentityTokenForMemberFromSession = withCookies(async (_req, _res, {cookies}) => {
try {
const email = cookies.get(cookieName, {
signed: true
});
return get(membersApi).getMemberIdentityToken(email);
} catch (e) {
throw new BadRequestError({
message: `Cookie ${cookieName} not found`
});
}
});
2019-04-05 09:57:14 +03:00
return {
exchangeTokenForSession,
deleteSession,
getMemberDataFromSession,
getIdentityTokenForMemberFromSession
2019-04-05 09:57:14 +03:00
};
};