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.
98 lines
2.9 KiB
98 lines
2.9 KiB
// session.js
|
|
// Copyright (C) 2022,2023 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
'use strict';
|
|
|
|
import util from 'node:util';
|
|
import passport from 'passport';
|
|
|
|
import { SiteService, SiteError } from '../../lib/site-lib.js';
|
|
|
|
export default class SessionService extends SiteService {
|
|
|
|
static get slug () { return 'session'; }
|
|
static get name ( ) { return 'SessionService'; }
|
|
|
|
constructor (dtp) {
|
|
super(dtp, SessionService);
|
|
}
|
|
|
|
async start ( ) {
|
|
await super.start();
|
|
|
|
passport.serializeUser(this.serializeUser.bind(this));
|
|
passport.deserializeUser(this.deserializeUser.bind(this));
|
|
}
|
|
|
|
async stop ( ) {
|
|
this.log.info(`stopping ${SessionService.name} service`);
|
|
}
|
|
|
|
middleware ( ) {
|
|
return async (req, res, next) => {
|
|
res.locals.user = req.user;
|
|
res.locals.query = req.query;
|
|
|
|
if (req.user) {
|
|
if (req.user.flags.isAdmin) {
|
|
res.locals.config = this.dtp.config;
|
|
res.locals.session = req.session;
|
|
res.locals.util = util;
|
|
}
|
|
}
|
|
|
|
return next();
|
|
};
|
|
}
|
|
|
|
authCheckMiddleware (options) {
|
|
const { membership: membershipService } = this.dtp.services;
|
|
options = Object.assign({
|
|
requireLogin: true,
|
|
requireEmailVerified: false,
|
|
requireMembership: false,
|
|
requireModerator: false,
|
|
requireAdmin: false,
|
|
}, options);
|
|
return async (req, res, next) => {
|
|
if (options.requireLogin && !req.user) {
|
|
return next(new SiteError(403, 'Login required'));
|
|
}
|
|
if (options.requireEmailVerified && (!req.user || !req.user.flags.isEmailVerified)) {
|
|
return next(new SiteError(403, `Must verify your email address to continue. Please check your spam folder for a welcome email from ${this.dtp.config.site.name}`));
|
|
}
|
|
if (options.requireMembership) {
|
|
res.locals.membership = await membershipService.getForUser(req.user);
|
|
if (!res.locals.membership) {
|
|
return next(new SiteError(403, 'Membership required'));
|
|
}
|
|
}
|
|
if (options.requireModerator && (!req.user || !req.user.flags.isModerator)) {
|
|
return next(new SiteError(403, 'Platform moderator privileges are required'));
|
|
}
|
|
if (options.requireAdmin && (!req.user || !req.user.flags.isAdmin)) {
|
|
return next(new SiteError(403, 'Platform administrator privileges are required'));
|
|
}
|
|
return next();
|
|
};
|
|
}
|
|
|
|
async serializeUser (user, done) {
|
|
return done(null, user._id);
|
|
}
|
|
|
|
async deserializeUser (userId, done) {
|
|
const { user: userService } = this.dtp.services;
|
|
try {
|
|
const user = await userService.getUserAccount(userId);
|
|
if (user.permissions && !user.permissions.canLogin) {
|
|
return done(null, null); // destroys user session without error
|
|
}
|
|
return done(null, user);
|
|
} catch (error) {
|
|
this.log.error('failed to deserialize user from session', { error });
|
|
return done(null, null);
|
|
}
|
|
}
|
|
}
|