react-laravel-sanctum
Version:
Easily integrate Laravel Sanctum and Breeze authentication into your React app.
173 lines (172 loc) • 5.62 kB
JavaScript
// src/context/AuthProvider.tsx
import { createContext, useContext, useEffect, useMemo, useState } from "react";
import { jsx } from "react/jsx-runtime";
var AuthContext = createContext(void 0);
function AuthProvider({ children, emailVerification = true, config }) {
const axiosInstance = useMemo(() => config.axiosInstance, [config.axiosInstance]);
const { signInRoute, signUpRoute, authenticationCheckRoute, sendEmailVerificationRoute, verifyEmailRoute, signOutRoute } = config;
const [authenticationState, setAuthenticationState] = useState({
user: null,
authenticated: null,
verified: null
});
const [loading, setLoading] = useState(true);
const { user, authenticated, verified } = authenticationState;
useEffect(() => {
checkAuthentication();
}, []);
const signIn = (credentials) => {
return new Promise(async (resolve, reject) => {
try {
await axiosInstance.post(signInRoute, credentials);
const user2 = await revalidate();
resolve({ mustVerifyEmail: false, signedIn: true, user: user2 });
} catch (error) {
if (error.response?.status === 409 && emailVerification) {
setAuthenticationState({ user: null, authenticated: true, verified: false });
resolve({ mustVerifyEmail: true, signedIn: false });
} else {
reject(error);
}
}
});
};
const signUp = (credentials) => {
return new Promise(async (resolve, reject) => {
try {
if (!signUpRoute) {
return reject(new Error("signUpRoute is not defined"));
}
await axiosInstance.post(signUpRoute, credentials);
if (emailVerification) {
setAuthenticationState({ user: null, authenticated: true, verified: false });
resolve({ mustVerifyEmail: true, signedIn: false });
} else {
const user2 = await revalidate();
resolve({ mustVerifyEmail: false, signedIn: true, user: user2 });
}
} catch (error) {
reject(error);
}
});
};
const revalidate = () => {
return new Promise(async (resolve, reject) => {
try {
const { data: user2 } = await axiosInstance.get(authenticationCheckRoute);
setAuthenticationState({ user: user2, authenticated: true, verified: true });
resolve(user2);
} catch (error) {
if (error.response?.status === 401) {
setAuthenticationState({ user: null, authenticated: false, verified: null });
resolve({});
} else if (error.response?.status === 409) {
setAuthenticationState({ user: null, authenticated: true, verified: false });
resolve({});
} else {
reject(error);
}
}
});
};
const handleSessionTimeout = (error) => {
if (error.response?.status === 401 || error.response?.status === 409) {
setAuthenticationState({ user: null, authenticated: false, verified: false });
}
};
const verifyEmail = (id, hash, expires, signature) => {
return new Promise(async (resolve, reject) => {
try {
const url = verifyEmailRoute?.(id, hash, expires, signature);
if (!url) {
return reject(new Error("verifyEmailRoute is not defined"));
}
await axiosInstance.get(url);
const user2 = await revalidate();
resolve(user2);
} catch (error) {
reject(error);
}
});
};
const sendEmailVerification = () => {
return new Promise(async (resolve, reject) => {
try {
if (!sendEmailVerificationRoute) {
return reject(new Error("sendEmailVerificationRoute is not defined"));
}
await axiosInstance.post(sendEmailVerificationRoute);
resolve();
} catch (error) {
reject(error);
}
});
};
const signOut = () => {
return new Promise(async (resolve, reject) => {
try {
await axiosInstance.post(signOutRoute);
setAuthenticationState({ user: null, authenticated: false, verified: false });
resolve();
} catch (error) {
reject(error);
}
});
};
const checkAuthentication = () => {
return new Promise(async (resolve, reject) => {
setLoading(true);
if (authenticated === null || verified === null) {
try {
await revalidate();
resolve(true);
} catch (error) {
if (error.response?.status === 401) {
setAuthenticationState({ user: null, authenticated: false, verified: null });
resolve(false);
} else if (error.response?.status === 409) {
setAuthenticationState({ user: null, authenticated: true, verified: false });
resolve(false);
} else {
reject(error);
}
} finally {
setLoading(false);
}
} else {
resolve(authenticated);
}
});
};
const setUser = (user2, authenticated2, verified2) => {
setAuthenticationState({ user: user2, authenticated: authenticated2, verified: verified2 });
};
return /* @__PURE__ */ jsx(
AuthContext.Provider,
{
value: {
authenticated,
user,
verified,
loading,
setUser,
signIn,
signUp,
verifyEmail,
sendEmailVerification,
signOut,
handleSessionTimeout
},
children
}
);
}
var useAuth = () => {
const context = useContext(AuthContext);
if (!context) throw new Error("useAuth should only be used inside <AuthProvider/>");
return context;
};
export {
AuthProvider,
useAuth
};