mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 01:41:46 +03:00
e90148e7c3
refs #9865 - see code comments
122 lines
3.3 KiB
JavaScript
122 lines
3.3 KiB
JavaScript
const url = require('url');
|
|
const common = require('../../../lib/common');
|
|
const constants = require('../../../lib/constants');
|
|
const config = require('../../../config');
|
|
const settingsCache = require('../../settings/cache');
|
|
const models = require('../../../models');
|
|
const session = require('express-session');
|
|
const SessionStore = require('./store');
|
|
const urlService = require('../../url');
|
|
|
|
const getOrigin = (req) => {
|
|
const origin = req.get('origin');
|
|
const referrer = req.get('referrer');
|
|
|
|
if (!origin && !referrer) {
|
|
return null;
|
|
}
|
|
|
|
if (origin) {
|
|
return origin;
|
|
}
|
|
|
|
const {protocol, host} = url.parse(referrer);
|
|
if (protocol && host) {
|
|
return `${protocol}//${host}`;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
let UNO_SESSIONIONA;
|
|
const getSession = (req, res, next) => {
|
|
if (!UNO_SESSIONIONA) {
|
|
UNO_SESSIONIONA = session({
|
|
store: new SessionStore(models.Session),
|
|
secret: settingsCache.get('session_secret'),
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
name: 'ghost-admin-api-session',
|
|
cookie: {
|
|
maxAge: constants.SIX_MONTH_MS,
|
|
httpOnly: true,
|
|
path: urlService.utils.getSubdir() + '/ghost',
|
|
sameSite: 'lax',
|
|
secure: urlService.utils.isSSL(config.get('url'))
|
|
}
|
|
});
|
|
}
|
|
return UNO_SESSIONIONA(req, res, next);
|
|
};
|
|
|
|
const createSession = (req, res, next) => {
|
|
getSession(req, res, function (err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
const origin = getOrigin(req);
|
|
if (!origin) {
|
|
return next(new common.errors.BadRequestError({
|
|
message: common.i18n.t('errors.middleware.auth.unknownOrigin')
|
|
}));
|
|
}
|
|
req.session.user_id = req.user.id;
|
|
req.session.origin = origin;
|
|
req.session.user_agent = req.get('user-agent');
|
|
req.session.ip = req.ip;
|
|
res.sendStatus(201);
|
|
});
|
|
};
|
|
|
|
const destroySession = (req, res, next) => {
|
|
req.session.destroy((err) => {
|
|
if (err) {
|
|
return next(new common.errors.InternalServerError({err}));
|
|
}
|
|
return res.sendStatus(204);
|
|
});
|
|
};
|
|
|
|
const getUser = (req, res, next) => {
|
|
if (!req.session || !req.session.user_id) {
|
|
req.user = null;
|
|
return next();
|
|
}
|
|
models.User.findOne({id: req.session.user_id})
|
|
.then((user) => {
|
|
req.user = user;
|
|
next();
|
|
}).catch(() => {
|
|
req.user = null;
|
|
next();
|
|
});
|
|
};
|
|
|
|
const cookieCsrfProtection = (req, res, next) => {
|
|
// If there is no origin on the session object it means this is a *new*
|
|
// session, that hasn't been initialised yet. So we don't need CSRF protection
|
|
if (!req.session.origin) {
|
|
return next();
|
|
}
|
|
|
|
const origin = getOrigin(req);
|
|
if (req.session.origin !== origin) {
|
|
return next(new common.errors.BadRequestError({
|
|
message: common.i18n.t('errors.middleware.auth.mismatchedOrigin', {
|
|
expected: req.session.origin,
|
|
actual: origin
|
|
})
|
|
}));
|
|
}
|
|
|
|
return next();
|
|
};
|
|
|
|
module.exports = exports = {
|
|
getSession,
|
|
cookieCsrfProtection,
|
|
safeGetSession: [getSession, cookieCsrfProtection],
|
|
createSession,
|
|
destroySession,
|
|
getUser
|
|
};
|