astro-community / astro-auth

The Easiest Way To Do Authentication In Astro šŸ§‘šŸ»ā€šŸš€
astro-auth-docs.vercel.app
99 stars 19 forks source link

[Example] How to use CredentialProvider #20

Open robodove opened 2 years ago

robodove commented 2 years ago
import AstroAuth from "@astro-auth/core";
import { CredentialProvider } from "@astro-auth/providers";
import db from "../../../db";
import bcrypt from "bcryptjs"

type SignUpOptions = {
  email: string;
  password: string;
  confirmPassword: string;
  signUp: true;
}

type SignInOptions = {
  email: string;
  password: string;
}

type AuthOptions = SignUpOptions

const signUpHandler = async (db: any, { email, password, confirmPassword }: Omit<SignUpOptions, "signUp">) => {
  if (password !== confirmPassword) return false;
  const hashedPassword = await bcrypt.hash(password, 10)
  try {
    await db.user.create({
      data: {
        email,
        hashedPassword,
      }
    })
    return true;
  } catch (e) {
    return false
  }
}

const signInHandler = async (db: any, { email, password }: Pick<SignInOptions, "email"|"password">) => {
    const user = await db.user.findFirst({ where: { email } })
    if (!user) return false;
    const match = await bcrypt.compare(password, user.hashedPassword)
    if (!match) return false;

    return true;
}

export const all = AstroAuth({
  authProviders: [
    CredentialProvider({
       async authorize({ email, password, signUp, confirmPassword }: AuthOptions) {
        if (signUp) {
          return signUpHandler(db, { email, password, confirmPassword })
        }

        return signInHandler(db, { email, password })
  },
})
  ],
  hooks: {},
});

Assuming passwords are hashed with bcryptjs and there is a db (in this case it's prisma with sqlite)