@saas-ui/auth-provider
Version:
Authentication provider primivites
231 lines (228 loc) • 5.89 kB
JavaScript
'use client'
// src/provider.tsx
import React2, {
createContext,
useState as useState2,
useContext,
useEffect,
useCallback
} from "react";
// src/use-promise.ts
import * as React from "react";
function usePromise(fn) {
const [isLoading, setLoading] = React.useState(false);
const [isResolved, setResolved] = React.useState(false);
const [isRejected, setRejected] = React.useState(false);
const [error, setError] = React.useState(null);
const [data, setData] = React.useState(null);
const call = (...params) => {
setLoading(true);
return fn(...params).then((data2) => {
setData(data2);
setResolved(true);
setLoading(false);
return data2;
}).catch((err) => {
setError(err);
setRejected(true);
setLoading(false);
throw err;
});
};
return [{ error, data, isLoading, isResolved, isRejected }, call];
}
// src/provider.tsx
import { jsx } from "react/jsx-runtime";
var createAuthContext = () => {
return createContext(null);
};
var AuthContext = createAuthContext();
var AuthProvider = ({
refetchUserOnWindowFocus = true,
onRestoreAuthState,
onLoadUser = () => Promise.resolve(null),
onSignup = () => Promise.resolve(null),
onLogin = () => Promise.resolve(null),
onVerifyOtp = () => Promise.resolve(null),
onLogout = () => Promise.resolve(),
onAuthStateChange,
onGetToken,
onResetPassword,
onUpdatePassword,
children
}) => {
const [isAuthenticated, setAuthenticated] = useState2(false);
const [user, setUser] = useState2();
const [isLoading, setLoading] = useState2(true);
const restoreRef = React2.useRef(false);
const isFetchingRef = React2.useRef(false);
const [error, setError] = useState2(null);
useEffect(() => {
if (onAuthStateChange) {
const unsubscribe = onAuthStateChange((user2) => {
setAuthenticated(!!user2);
});
return () => {
unsubscribe == null ? void 0 : unsubscribe();
};
}
}, []);
useEffect(() => {
const restoreState = async () => {
restoreRef.current = true;
await (onRestoreAuthState == null ? void 0 : onRestoreAuthState());
await loadUser();
restoreRef.current = false;
};
if (!restoreRef.current) {
restoreState();
}
}, [onRestoreAuthState]);
const loadUser = useCallback(async () => {
try {
if (isFetchingRef.current) {
return;
}
setError(null);
if ((typeof onGetToken === "undefined" || await onGetToken()) && !isFetchingRef.current) {
isFetchingRef.current = true;
const user2 = await onLoadUser();
if (user2) {
setUser(user2);
setAuthenticated(true);
} else {
setAuthenticated(false);
setUser(null);
}
}
} catch (error2) {
setError(error2);
setAuthenticated(false);
setUser(null);
} finally {
isFetchingRef.current = false;
setLoading(false);
}
}, [onLoadUser, onGetToken]);
useEffect(() => {
if (!refetchUserOnWindowFocus) {
return;
}
const onWindowFocus = async () => {
loadUser();
};
window.addEventListener("focus", onWindowFocus);
return () => {
if (onWindowFocus) {
window.removeEventListener("focus", onWindowFocus);
}
};
}, [loadUser, refetchUserOnWindowFocus]);
const signUp = useCallback(
async (params, options) => {
const result = await onSignup(params, options);
loadUser();
return result;
},
[onSignup]
);
const logIn = useCallback(
async (params, options) => {
const result = await onLogin(params, options);
loadUser();
return result;
},
[onLogin]
);
const logOut = useCallback(
async (options) => {
await onLogout(options);
setUser(null);
setAuthenticated(false);
},
[onLogout]
);
const verifyOtp = useCallback(
async (params, options) => {
const result = await onVerifyOtp(params, options);
return result;
},
[onVerifyOtp]
);
const resetPassword = useCallback(
async (params, options) => {
return await (onResetPassword == null ? void 0 : onResetPassword(params, options));
},
[onResetPassword]
);
const updatePassword = useCallback(
async (params, options) => {
return await (onUpdatePassword == null ? void 0 : onUpdatePassword(params, options));
},
[onUpdatePassword]
);
const getToken = useCallback(async () => {
return onGetToken == null ? void 0 : onGetToken();
}, [onGetToken]);
const value = {
isAuthenticated,
isLoggingIn: isAuthenticated && !user,
isLoading,
user,
signUp,
logIn,
logOut,
verifyOtp,
loadUser,
getToken,
resetPassword,
updatePassword,
error
};
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
};
var useAuth = () => {
const context = useContext(AuthContext);
if (context === null) {
throw new Error(
"Auth context missing, did you forget to wrap your app in AuthProvider?"
);
}
return context;
};
var useCurrentUser = () => {
return useAuth().user;
};
var useLogin = ({ action = "logIn" } = {}) => {
const auth = useAuth();
const fn = auth[action] || auth["logIn"];
return usePromise(fn);
};
var useSignUp = () => {
const { signUp } = useAuth();
return usePromise(signUp);
};
var useOtp = () => {
const { verifyOtp } = useAuth();
return usePromise(verifyOtp);
};
var useResetPassword = () => {
const { resetPassword } = useAuth();
return usePromise(resetPassword);
};
var useUpdatePassword = () => {
const { updatePassword } = useAuth();
return usePromise(updatePassword);
};
export {
AuthContext,
AuthProvider,
useAuth,
useCurrentUser,
useLogin,
useOtp,
useResetPassword,
useSignUp,
useUpdatePassword
};
//# sourceMappingURL=index.mjs.map