You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.0 KiB
117 lines
3.0 KiB
// session.js
|
|
// Copyright (C) 2022 DTP Technologies, LLC
|
|
// License: Apache-2.0
|
|
|
|
'use strict';
|
|
|
|
const util = require('util');
|
|
|
|
const passport = require('passport');
|
|
|
|
const { SiteError, SiteService } = require('../../lib/site-lib');
|
|
|
|
class SessionService extends SiteService {
|
|
|
|
constructor (dtp) {
|
|
super(dtp, module.exports);
|
|
}
|
|
|
|
async start ( ) {
|
|
await super.start();
|
|
|
|
passport.serializeUser(this.serializeUser.bind(this));
|
|
passport.deserializeUser(this.deserializeUser.bind(this));
|
|
}
|
|
|
|
async stop ( ) {
|
|
this.log.info(`stopping ${module.exports.name} service`);
|
|
await super.stop();
|
|
}
|
|
|
|
middleware ( ) {
|
|
return async (req, res, next) => {
|
|
res.locals.util = util;
|
|
|
|
res.locals.user = req.user;
|
|
res.locals.query = req.query;
|
|
|
|
res.locals.config = this.dtp.config;
|
|
if (req.session) {
|
|
res.locals.session = req.session;
|
|
}
|
|
|
|
return next();
|
|
};
|
|
}
|
|
|
|
authCheckMiddleware (options) {
|
|
options = Object.assign({
|
|
requireLogin: true,
|
|
requireAdmin: false,
|
|
useRedirect: true,
|
|
loginUri: '/welcome/login',
|
|
}, options);
|
|
return async (req, res, next) => {
|
|
if (options.requireLogin && !req.user) {
|
|
if (options.useRedirect) {
|
|
req.session.loginReturnTo = req.url;
|
|
await this.saveSession(req);
|
|
this.log.info('redirecting to login', { returnTo: req.url });
|
|
return res.redirect(options.loginUri);
|
|
}
|
|
return next(new SiteError(403, 'Must sign in to continue'));
|
|
}
|
|
if (options.requireAdmin && (!req.user || !req.user.flags.isAdmin)) {
|
|
return next(new SiteError(403, 'Administrator privileges are required'));
|
|
}
|
|
return next();
|
|
};
|
|
}
|
|
|
|
async serializeUser (user, done) {
|
|
if (user.coreUserId) {
|
|
return done(null, `core:${user._id}`);
|
|
}
|
|
return done(null, `local:${user._id}`);
|
|
}
|
|
|
|
async deserializeUser (userTag, done) {
|
|
const { coreNode: coreNodeService, user: userService } = this.dtp.services;
|
|
const [serviceName, userId] = userTag.split(':');
|
|
try {
|
|
let user;
|
|
switch (serviceName) {
|
|
case 'core':
|
|
user = await coreNodeService.getUserByLocalId(userId);
|
|
user.type = 'CoreUser';
|
|
delete user.core.oauth;
|
|
delete user.core.__v;
|
|
delete user.__v;
|
|
delete user.flags._id;
|
|
delete user.permissions._id;
|
|
delete user.stats._id;
|
|
delete user.optIn._id;
|
|
break;
|
|
|
|
case 'local':
|
|
user = await userService.getLocalUserAccount(userId);
|
|
user.type = 'User';
|
|
break;
|
|
}
|
|
if (user && user.permissions && !user.permissions.canLogin) {
|
|
return done(null, null); // destroy the session
|
|
}
|
|
return done(null, user);
|
|
} catch (error) {
|
|
this.log.error('failed to deserialize user from session', { error });
|
|
return done(null, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
logId: 'session',
|
|
index: 'session',
|
|
className: 'SessionService',
|
|
create: (dtp) => { return new SessionService(dtp); },
|
|
};
|