@qelos/auth
Version:
Express Passport authentication service
69 lines (64 loc) • 2.42 kB
text/typescript
import { defaultAuthType } from '../../config';
import { getUser, comparePassword, setToken, clearOldTokens } from '../services/users';
import { Strategy } from 'passport-local';
import { UserDocument, UserModel } from '../models/user';
import { getWorkspaceConfiguration } from '../services/workspace-configuration';
import logger from '../services/logger';
import { getWorkspaceForUser } from '../services/workspaces';
module.exports = new Strategy(
{
usernameField: 'username',
passwordField: 'password',
session: false,
passReqToCallback: true,
},
async (req, username, password, done) => {
const query: {
username: string;
tenant: undefined | string;
roles?: { $in: string[] };
} = { username: username.trim() || req.body?.email?.trim(), tenant: req.headers.tenant as string };
const authType = req.body.authType || defaultAuthType;
if (req.body.roles && req.body.roles instanceof Array) {
query.roles = { $in: req.body.roles };
}
const preSelectedWorkspace = req.body.workspace;
const [wsConfig, user] = await Promise.all([
getWorkspaceConfiguration(query.tenant),
getUser(query)
.then((user) => user && comparePassword((user as unknown as UserModel), password))
.catch(() => null)
]);
if (!user) {
return done({ message: 'Invalid username or password' });
}
let workspace;
if (wsConfig.isActive) {
try {
workspace = await getWorkspaceForUser(query.tenant, user._id, preSelectedWorkspace || user.lastLogin?.workspace || user.tokens?.at(-1)?.metadata?.workspace);
} catch (err) {
logger.log('Error getting workspace', query);
}
}
setToken({ user: user as any as UserDocument, workspace }, authType)
.then(({ user, token, refreshToken, cookieToken }) => {
done(null, {
tenant: query.tenant,
token,
refreshToken,
cookieToken,
workspace,
user: {
username: user.username,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
name: user.name || user.fullName || `${user.firstName} ${user.lastName}`,
roles: user.roles,
},
});
})
.catch((err) => done(err))
.finally(() => setTimeout(() => clearOldTokens((user as any)._id).catch(), 1))
}
);