function SessionFromToken({
    getTokenFromRequest,
    getLookupFromToken,
    findUserByLookup,
    createSession,
    callNextWithError
}) {
    /**
     * @param {Req} req
     * @param {Res} res
     * @param {Next} next
     * @returns {Promise<void>}
     */
    async function handler(req, res, next) {
        try {
            const token = await getTokenFromRequest(req);
            if (!token) {
                return next();
            }
            const email = await getLookupFromToken(token);
            if (!email) {
                return next();
            }
            const user = await findUserByLookup(email);
            if (!user) {
                return next();
            }
            await createSession(req, res, user);
            next();
        } catch (err) {
            if (callNextWithError) {
                next(err);
            } else {
                next();
            }
        }
    }

    return handler;
}
Returns a connect middleware function which exchanges a token for a session

@template Token
@template Lookup

@param { object } deps
@param { (req: Req) => Promise<Token> } deps.getTokenFromRequest
@param { (token: Token) => Promise<Lookup> } deps.getLookupFromToken
@param { (lookup: Lookup) => Promise<User> } deps.findUserByLookup
@param { (req: Req, res: Res, user: User) => Promise<void> } deps.createSession
@param { boolean } deps.callNextWithError - Whether next should be call with an error or just pass through

@returns {RequestHandler}