I had a first try on using fp-ts to do user validation with passport.js.
import argon2 from "argon2";
import * as E from "fp-ts/lib/Either";
import { flow, pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/lib/Option";
import * as TE from "fp-ts/lib/TaskEither";
import * as passport from "passport";
import * as PassportLocal from "passport-local";
import logger from "./logger";
import {
UserProfile,
UserProfileRepository,
} from "../db/entities/user_profile";
const verifyPassport: PassportLocal.VerifyFunction = (
userName: string,
password: string,
done
) => {
const onUserFound = (optionUser: O.Option<UserProfile>) => {
const onSome = (user: UserProfile) => () =>
argon2
.verify(user.userPassword, password)
.then((valid) =>
valid
? E.right(user)
: E.left(new Error(`invalid user name or password`))
)
.catch(E.left);
const onNone = () =>
TE.left(new Error(`user name ${userName} doesn't exist`));
return pipe(optionUser, O.match(onNone, onSome));
};
pipe(
userName,
UserProfileRepository.findOneByUserName /*returns TE.TaskEither<Error, O.Option<UserProfile>> */,
TE.chain(onUserFound),
TE.bimap(
({ message }) => done(null, false, { message }),
(user) => done(null, user)
)
)();
};
Top comments (0)