prostgles-client
Version:
Reactive client for Postgres
246 lines (245 loc) • 10.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ERR_CODE_MESSAGES = exports.useAuthState = void 0;
const prostgles_types_1 = require("prostgles-types");
const reactImports_1 = require("../hooks/reactImports");
const { useEffect, useState } = reactImports_1.reactImports;
const loginStates = ["login", "loginTotp", "loginTotpRecovery"];
const useAuthState = ({ auth }) => {
const [loading, setIsLoading] = useState(false);
const [state, setState] = useState("login");
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [emailVerificationCode, setEmailVerificationCode] = useState("");
const [totpToken, setTotpToken] = useState("");
const [totpRecoveryCode, setTotpRecoveryCode] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [usernamesWithPassword, setUsernamesWithPassword] = useState([]);
const [error, _setError] = useState("");
const [result, setResult] = useState();
const [authResponse, setAuthResponse] = useState();
// const [searchParams, setSearchParams] = useSearchParams();
// const verifiedEmail = searchParams.get(EMAIL_CONFIRMED_SEARCH_PARAM);
// useEffect(() => {
// if (!verifiedEmail) return;
// setAuthResponse({
// success: true,
// message: SIGNUP_CODE_MESSAGES["email-verified"],
// });
// }, [verifiedEmail, setSearchParams]);
useEffect(() => {
_setError("");
}, [username, password, totpToken, totpRecoveryCode, confirmPassword]);
const formHandlers = state === "login" && auth.loginType === "email" ?
{
state,
username,
setUsername,
...(usernamesWithPassword.includes(username) && {
password,
setPassword,
}),
onCall: auth.login,
}
: state === "login" && auth.loginType === "email+password" ?
{
state,
username,
setUsername,
password,
setPassword,
onCall: auth.login,
}
: state === "loginTotp" && auth.login ?
{
state,
totpToken,
setTotpToken,
onCall: auth.login,
}
: state === "loginTotpRecovery" && auth.login ?
{
state,
totpRecoveryCode,
setTotpRecoveryCode,
onCall: auth.login,
}
: state === "registerWithPassword" && auth.signupWithEmailAndPassword ?
{
state,
username,
setUsername,
password,
setPassword,
confirmPassword,
setConfirmPassword,
onCall: auth.signupWithEmailAndPassword,
result,
}
: state === "registerWithPasswordConfirmationCode" && auth.signupWithEmailAndPassword ?
{
state,
username,
emailVerificationCode,
setEmailVerificationCode,
onCall: () => {
if (!auth.confirmEmail) {
throw new Error("unexpected");
}
return auth.confirmEmail({
email: username,
code: emailVerificationCode,
});
},
result,
}
: undefined;
const isOnLogin = loginStates.some((v) => v === state);
const registerTypeAllowed = "registerWithPassword";
const onAuthCall = async () => {
var _a, _b, _c;
const formData = {
username,
password,
remember_me: false,
totp_token: totpToken,
totp_recovery_code: totpRecoveryCode,
};
const errorMap = {
"no match": "Invalid credentials",
};
const setError = (err) => {
_setError(err);
};
const setErrorWithInfo = (err) => {
return setError(err === "no match" ? errorMap[err] : err);
};
if (!(formHandlers === null || formHandlers === void 0 ? void 0 : formHandlers.onCall)) {
return setError("Invalid state");
}
/**
* Validate form data
*/
if (isOnLogin) {
if (!username) {
return setError("Username/email cannot be empty");
}
if (!password && formHandlers.setPassword) {
return setError("Password cannot be empty");
}
if (formHandlers.state === "loginTotp" && !totpToken) {
return setError("Token cannot be empty");
}
if (formHandlers.state === "loginTotpRecovery" && !totpRecoveryCode) {
return setError("Recovery code cannot be empty");
}
}
else {
if (!username) {
return setError("Email cannot be empty");
}
if (formHandlers.state === "registerWithPassword") {
if (!password) {
return setError("Password cannot be empty");
}
else if (password !== confirmPassword) {
return setError("Passwords do not match");
}
}
}
const res = await formHandlers.onCall(formData);
if (!res.success) {
if (state === "login" &&
res.code === "password-missing" &&
!usernamesWithPassword.includes(username)) {
setUsernamesWithPassword([...usernamesWithPassword, username]);
}
if (state === "login" && res.code === "email-not-confirmed") {
setAuthResponse({
success: false,
message: exports.ERR_CODE_MESSAGES[res.code],
});
setState("registerWithPasswordConfirmationCode");
}
if (res.code === "totp-token-missing") {
setState("loginTotp");
}
else if (res.code !== "password-missing") {
const errorMessage = (_a = res.message) !== null && _a !== void 0 ? _a : (0, prostgles_types_1.getProperty)(exports.ERR_CODE_MESSAGES, res.code);
setErrorWithInfo(errorMessage !== null && errorMessage !== void 0 ? errorMessage : "Error");
}
}
else {
if ("redirect_url" in res && res.redirect_url) {
window.location.href = res.redirect_url;
}
if (state === "registerWithPassword" || res.code === "magic-link-sent") {
setState("registerWithPasswordConfirmationCode");
}
let message = (_c = (_b = (res.code && SIGNUP_CODE_MESSAGES[res.code])) !== null && _b !== void 0 ? _b : res.message) !== null && _c !== void 0 ? _c : "Success";
if (formHandlers.state === "registerWithPasswordConfirmationCode") {
message = SIGNUP_CODE_MESSAGES["email-verified"];
setState("login");
}
if (!res.redirect_url) {
setAuthResponse({
...res,
message,
});
}
}
setResult(res);
return res;
};
return {
formHandlers,
error,
setState,
state,
loading,
onAuthCall: () => {
setIsLoading(true);
return onAuthCall().finally(() => setIsLoading(false));
},
isOnLogin,
registerTypeAllowed,
result,
authResponse,
clearAuthResponse: () => {
setAuthResponse(undefined);
// setSearchParams({});
},
};
};
exports.useAuthState = useAuthState;
exports.ERR_CODE_MESSAGES = {
"no-match": "Invalid credentials",
"password-missing": "Password cannot be empty",
"totp-token-missing": "Token cannot be empty",
"invalid-totp-recovery-code": "Invalid recovery code",
"rate-limit-exceeded": "Too many failed attempts",
"email-not-confirmed": "Email not confirmed. Please check your email and open the confirmation url or enter the provided code",
"expired-magic-link": "Magic link expired",
"inactive-account": "Account is inactive",
"invalid-password": "Invalid or missing password",
"invalid-totp-code": "Invalid totp code",
"invalid-username": "Invalid or missing username",
"is-from-magic-link": "Cannot login with password",
"is-from-OAuth": "Cannot login with password",
"server-error": "Server error",
"something-went-wrong": "Something went wrong",
"user-already-registered": "User already registered",
"username-missing": "Username cannot be empty",
"weak-password": "Password is too weak",
"expired-email-confirmation-code": "Email confirmation code expired",
"invalid-email-confirmation-code": "Invalid email confirmation code",
"invalid-magic-link": "Invalid magic link",
"used-magic-link": "Magic link already used",
"invalid-email": "Invalid or missing email",
};
const SIGNUP_CODE_MESSAGES = {
"already-registered-but-did-not-confirm-email": "Email verification re-sent. Open the verification url or enter the code to confirm your email",
"email-verification-code-sent": "Email verification sent. Open the verification url or enter the code to confirm your email",
"email-verified": "Your email has been confirmed. You can now sign in",
"magic-link-sent": "Magic link sent. Open the url from your email to login",
};