DTP Social Engine
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.
 
 
 
 
 

112 lines
2.9 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();
this.log.info(`starting ${module.exports.name} service`);
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.getUserAccount(userId);
user.type = 'User';
break;
}
return done(null, user);
} catch (error) {
this.log.error('failed to deserialize user from session', { error });
return done(null, null);
}
}
}
module.exports = {
slug: 'session',
name: 'session',
create: (dtp) => { return new SessionService(dtp); },
};