Authentication
Authentication​
Client side validation​
Formik and Yup are used to handle all client side validation.
Supabase Authentication​
Login​
Login is handled by using React Query using the useSignIn custom hook
import { showNotification } from "@mantine/notifications";
import { SupabaseClient } from "@supabase/auth-helpers-react";
import Router from "next/router";
import { useMutation } from "react-query";
import { DBTypes } from "../supabase/db-types";
type auth = {
email: string;
password: string;
supabase: SupabaseClient<DBTypes>;
};
const singIn = async ({ email, password, supabase }: auth) => {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
showNotification({ message: error?.message, color: "red" });
throw new Error(error?.message);
}
Router.push("/room/list");
showNotification({ message: "Sign in success", color: "green" });
return data;
};
const useSignIn = ({ email, password, supabase }: auth) => {
return useMutation("singin", () => singIn({ email, password, supabase }));
};
export default useSignIn;
this makes it easy to handle the loading state and error state of the login form
const handleOAuth = async (provider: Provider) => {
await supabase.auth.signInWithOAuth({ provider, options: { redirectTo: "/" } });
};
const handleSignIn = async () => login.mutate();
const handleDummyAccLogin = async () => {
await formik.setFieldValue("email", "salt22@gmail.com");
await formik.setFieldValue("password", "salt1234");
await handleSignIn();
};
const formik = useFormik({
initialValues: { email: "", password: "" },
validationSchema: signInValidationSchema,
onSubmit: handleSignIn,
});
const useSignInParams = {
email: formik.values.email,
password: formik.values.password,
supabase,
};
const login = useSignIn(useSignInParams);
Signup​
Signup is handled by using React Query using the useSignUp custom hook
import { showNotification } from "@mantine/notifications";
import { SupabaseClient } from "@supabase/auth-helpers-react";
import Router from "next/router";
import { useMutation } from "react-query";
import { DBTypes } from "../supabase/db-types";
type auth = {
email: string;
password: string;
username: string;
supabase: SupabaseClient<DBTypes>;
};
const signUp = async ({ email, password, username, supabase }: auth) => {
const { data, error } = await supabase.auth.signUp({
email,
password,
});
if (error) {
showNotification({ message: error?.message, color: "red" });
throw new Error(error?.message);
}
const { data: userData, error: userErr } = await supabase.auth.getUser();
if (userErr) throw new Error(userErr.message);
const { error: updateUsernameErr } = await supabase.from("profiles").update({ username }).eq("id", userData.user.id);
if (updateUsernameErr) throw new Error(updateUsernameErr.message);
Router.push("/");
showNotification({ message: "Sign Up success", color: "green" });
return data;
};
const useSignUp = ({ email, password, supabase, username }: auth) => {
return useMutation("Signup", () => signUp({ email, password, supabase, username }));
};
export default useSignUp;
again this makes it easy to handle the loading state and error state of the signup form
const handleSignUp = async () => signUp.mutate();
const formik = useFormik({
initialValues: { email: "", password: "", username: "" },
validationSchema: signUpValidationSchema,
onSubmit: handleSignUp,
});
const useSignUpParams = {
email: formik.values.email,
password: formik.values.password,
username: formik.values.username,
supabase,
};
const signUp = useSignUp(useSignUpParams);
const authHandler = async () => {
setIsLoading(true);
const email = usernameToEmail(formik.values.username);
const password = formik.values.password;
const userData = { email, password };
let error: AuthError | null = null;
let response: AuthResponse | null = null;
if (formState == "Login") response = await supabase.auth.signInWithPassword(userData);
if (formState === "Signup") response = await supabase.auth.signUp(userData);
if (response) error = response.error || null;
if (error) {
setAuthError(error?.message || "Error Occured");
} else {
toast.success("Authenticated");
router.push("/");
setAuthError(null);
}
setIsLoading(false);
};
using the supabase sdk built in method for authentication
Logout​
Using the supabase sdk a simple function will log the user out
const handleLogout = async (e: SyntheticEvent) => {
e.preventDefault();
const { error } = await supabase.auth.signOut();
if (error) return showNotification({ message: error.message, color: "red" });
showNotification({ message: "Sign out success", color: "green" });
router.push("/");
};