mirror of
https://github.com/fergalmoran/radio-otherway.git
synced 2025-12-22 09:50:29 +00:00
Add login error handlers
This commit is contained in:
7
web/.env
7
web/.env
@@ -5,11 +5,4 @@ QSTASH_CURRENT_SIGNING_KEY=khs3lpVBv1QtV/L9MTdXlcnoI8tTlg0aDfrFz+o8utA=
|
||||
#auth
|
||||
GOOGLE_APPLICATION_CREDENTIALS=serviceAccount.json
|
||||
|
||||
#calendar api
|
||||
GOOGLE_CALENDAR_PROJECT_ID=47147490249
|
||||
GOOGLE_CALENDAR_ID=geh501qel59lf3505v2huebo18@group.calendar.google.com
|
||||
LIVE_GOOGLE_CALENDAR_ID=geh501qel59lf3505v2huebo18@group.calendar.google.com
|
||||
DEBUG_GOOGLE_CALENDAR_ID=7732f7973f574db2638371394769a94aad5e38b98362d528cd985728d98cf3bd@group.calendar.google.com
|
||||
|
||||
GOOGLE_CALENDAR_API_KEY=AIzaSyAMvrSrwqvz9o4Y8b-0zneU-REWDIzuKR0
|
||||
GOOGLE_CALENDAR_CREDENTIALS_CLIENT_EMAIL="otherway-calendar-proxy@radio-otherway.iam.gserviceaccount.com"
|
||||
|
||||
@@ -21,11 +21,41 @@ const LoginPage = () => {
|
||||
const login = async (
|
||||
event: React.SyntheticEvent<HTMLButtonElement>
|
||||
): Promise<void> => {
|
||||
setError("");
|
||||
try {
|
||||
const result = await signIn(email, password);
|
||||
if (result && result.user) {
|
||||
router.push("/");
|
||||
} else {
|
||||
setError("Unable to log you in, please check your email & password");
|
||||
}
|
||||
} catch (err) {
|
||||
setError("Unable to log you in, please check your email & password");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="font-body max-w-lg rounded-md bg-base-100 p-10 text-base-content shadow-md md:flex-1">
|
||||
<h3 className="font-title my-4 text-2xl font-semibold">Account Login</h3>
|
||||
{error && (
|
||||
<div className="mb-4 shadow-lg alert alert-error">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="flex-shrink-0 w-6 h-6 stroke-current"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col space-y-5">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<label htmlFor="email" className="text-sm">
|
||||
@@ -88,26 +118,6 @@ const LoginPage = () => {
|
||||
<GoogleButton onClick={signInWithGoogle} />
|
||||
<FacebookButton onClick={signInWithFacebook} />
|
||||
</div>
|
||||
{error && (
|
||||
<div className="alert alert-error shadow-lg">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6 flex-shrink-0 stroke-current"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,173 +5,154 @@ import { IoLogoFacebook, IoLogoGoogle, IoLogoTwitter } from "react-icons/io";
|
||||
import { AiOutlineExclamationCircle } from "react-icons/ai";
|
||||
|
||||
import { Info } from "react-feather";
|
||||
import useFirebaseAuth from "@/lib/auth/signin";
|
||||
import { FacebookButton, GoogleButton, TwitterButton } from "@/components/widgets/buttons/social";
|
||||
import ToastService from "@/components/widgets/toast";
|
||||
import { validateEmail } from "@/lib/util/validationUtils";
|
||||
|
||||
const SignupPage = () => {
|
||||
return <div>Signup Page</div>;
|
||||
// const {
|
||||
// signInWithGoogle,
|
||||
// signInWithFacebook,
|
||||
// signInWithTwitter,
|
||||
// profile,
|
||||
// signUp,
|
||||
// linkAccounts,
|
||||
// } = useFirebaseAuth();
|
||||
// const router = useRouter();
|
||||
// const [error, setError] = React.useState("");
|
||||
// const [email, setEmail] = React.useState("");
|
||||
// const [password, setPassword] = React.useState("");
|
||||
// const [confirmPassword, setConfirmPassword] = React.useState("");
|
||||
|
||||
// const [linking, setLinking] = React.useState(false);
|
||||
// const register = async (
|
||||
// $event: React.SyntheticEvent<HTMLButtonElement>
|
||||
// ): Promise<void> => {
|
||||
// $event.preventDefault();
|
||||
const {
|
||||
signInWithGoogle,
|
||||
signInWithFacebook,
|
||||
signInWithTwitter,
|
||||
signUp
|
||||
} = useFirebaseAuth();
|
||||
const router = useRouter();
|
||||
const [error, setError] = React.useState("");
|
||||
const [email, setEmail] = React.useState("");
|
||||
const [password, setPassword] = React.useState("");
|
||||
const [confirmPassword, setConfirmPassword] = React.useState("");
|
||||
const register = async (
|
||||
$event: React.SyntheticEvent<HTMLButtonElement>
|
||||
): Promise<void> => {
|
||||
setError("");
|
||||
$event.preventDefault();
|
||||
if (!validateEmail(email)) {
|
||||
setError("Please enter a valid email address");
|
||||
return;
|
||||
}
|
||||
if (!password) {
|
||||
setError("Please enter a password");
|
||||
return;
|
||||
}
|
||||
if (password !== confirmPassword) {
|
||||
setError("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
setError("");
|
||||
const result = await signUp(email, password);
|
||||
if (result === "") {
|
||||
setError("");
|
||||
ToastService.success("Account successfully created");
|
||||
router.push("/");
|
||||
} else if (result === "auth/email-already-in-use") {
|
||||
// setError("");
|
||||
// setLinking(false);
|
||||
// const result = await signUp(email, password);
|
||||
// if (result === "auth/email-already-in-use") {
|
||||
// setLinking(true);
|
||||
// setError("");
|
||||
// // setError("This email address has already been used to create an account.");
|
||||
// } else if (result === "auth/invalid-email") {
|
||||
// setError("Please enter a correct email address");
|
||||
// } else {
|
||||
// setError("Unable to create an account for you at this time");
|
||||
// }
|
||||
// };
|
||||
// return (
|
||||
// <div className="max-w-lg p-10 rounded-md shadow-md font-body bg-base-100 text-base-content md:flex-1">
|
||||
// <h3 className="my-4 text-2xl font-semibold font-title">
|
||||
// Create New Account
|
||||
// </h3>
|
||||
// {error && (
|
||||
// <div className="mb-4 shadow-lg alert alert-error">
|
||||
// <div>
|
||||
// <svg
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// className="flex-shrink-0 w-6 h-6 stroke-current"
|
||||
// fill="none"
|
||||
// viewBox="0 0 24 24"
|
||||
// >
|
||||
// <path
|
||||
// strokeLinecap="round"
|
||||
// strokeLinejoin="round"
|
||||
// strokeWidth="2"
|
||||
// d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
// />
|
||||
// </svg>
|
||||
// <span>{error}</span>
|
||||
// </div>
|
||||
// </div>
|
||||
// )}
|
||||
// <form action="#" className="flex flex-col space-y-5">
|
||||
// <div className="flex flex-col space-y-1">
|
||||
// <label htmlFor="email" className="text-sm">
|
||||
// Email address
|
||||
// </label>
|
||||
// <input
|
||||
// type="email"
|
||||
// id="email"
|
||||
// autoFocus
|
||||
// className="input-bordered input-primary input input-sm"
|
||||
// value={email}
|
||||
// onChange={(event) => {
|
||||
// setEmail(event.target.value);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// <div className="flex flex-col space-y-1">
|
||||
// <div className="flex items-center justify-between">
|
||||
// <label htmlFor="password" className="text-sm">
|
||||
// Password
|
||||
// </label>
|
||||
// </div>
|
||||
// <input
|
||||
// type="password"
|
||||
// id="password"
|
||||
// className="input-bordered input-primary input input-sm"
|
||||
// value={password}
|
||||
// onChange={(event) => {
|
||||
// setPassword(event.target.value);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// <div className="flex flex-col space-y-1">
|
||||
// <div className="flex items-center justify-between">
|
||||
// <label htmlFor="password" className="text-sm">
|
||||
// Repeat password
|
||||
// </label>
|
||||
// </div>
|
||||
// <input
|
||||
// type="password"
|
||||
// id="password"
|
||||
// className="input-bordered input-primary input input-sm"
|
||||
// value={confirmPassword}
|
||||
// onChange={(event) => {
|
||||
// setConfirmPassword(event.target.value);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// <div>
|
||||
// <button
|
||||
// className="w-full btn-primary btn"
|
||||
// onClick={(event) => {
|
||||
// void register(event);
|
||||
// }}
|
||||
// >
|
||||
// Register for Account
|
||||
// </button>
|
||||
// </div>
|
||||
setError("This email address has already been used to create an account.");
|
||||
} else if (result === "auth/invalid-email") {
|
||||
setError("Please enter a correct email address");
|
||||
} else {
|
||||
setError("Unable to create an account for you at this time");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="max-w-lg p-10 rounded-md shadow-md font-body bg-base-100 text-base-content md:flex-1">
|
||||
<h3 className="my-4 text-2xl font-semibold font-title">
|
||||
Create New Account
|
||||
</h3>
|
||||
{error && (
|
||||
<div className="mb-4 shadow-lg alert alert-error">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="flex-shrink-0 w-6 h-6 stroke-current"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<form action="#" className="flex flex-col space-y-5">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<label htmlFor="email" className="text-sm">
|
||||
Email address
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
autoFocus
|
||||
className="input-bordered input-primary input input-sm"
|
||||
value={email}
|
||||
onChange={(event) => {
|
||||
setEmail(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<label htmlFor="password" className="text-sm">
|
||||
Password
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
className="input-bordered input-primary input input-sm"
|
||||
value={password}
|
||||
onChange={(event) => {
|
||||
setPassword(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<label htmlFor="password" className="text-sm">
|
||||
Repeat password
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
className="input-bordered input-primary input input-sm"
|
||||
value={confirmPassword}
|
||||
onChange={(event) => {
|
||||
setConfirmPassword(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
className="w-full btn-primary btn"
|
||||
onClick={(event) => {
|
||||
void register(event);
|
||||
}}
|
||||
>
|
||||
Register for Account
|
||||
</button>
|
||||
</div>
|
||||
|
||||
// <div className="flex flex-col space-y-5">
|
||||
// <span className="flex items-center justify-center space-x-2">
|
||||
// <span className="h-px bg-gray-400 w-14" />
|
||||
// <span className="font-normal text-gray-500">or sign up with</span>
|
||||
// <span className="h-px bg-gray-400 w-14" />
|
||||
// </span>
|
||||
// <div className="flex items-center justify-center gap-4">
|
||||
// <button
|
||||
// type="button"
|
||||
// className="w-1/3 gap-2 btn"
|
||||
// onClick={signInWithTwitter}
|
||||
// >
|
||||
// <div className="text-base-content">
|
||||
// <IoLogoTwitter />
|
||||
// </div>
|
||||
// <span className="text-sm font-medium text-base-content">
|
||||
// Twitter
|
||||
// </span>
|
||||
// </button>
|
||||
// <button
|
||||
// type="button"
|
||||
// className="w-1/3 gap-2 btn"
|
||||
// onClick={signInWithGoogle}
|
||||
// >
|
||||
// <div className="text-base-content">
|
||||
// <IoLogoGoogle />
|
||||
// </div>
|
||||
// <span className="text-sm font-medium text-base-content">
|
||||
// Gmail
|
||||
// </span>
|
||||
// </button>
|
||||
// <button
|
||||
// type="button"
|
||||
// className="w-1/3 gap-2 btn"
|
||||
// onClick={signInWithFacebook}
|
||||
// >
|
||||
// <div className="text-base-content">
|
||||
// <IoLogoFacebook />
|
||||
// </div>
|
||||
// <span className="text-sm font-medium text-base-content">
|
||||
// Facebook
|
||||
// </span>
|
||||
// </button>
|
||||
// </div>
|
||||
// </div>
|
||||
// </form>
|
||||
// </div>
|
||||
// );
|
||||
<div className="flex flex-col space-y-5">
|
||||
<span className="flex items-center justify-center space-x-2">
|
||||
<span className="h-px bg-gray-400 w-14" />
|
||||
<span className="font-normal text-gray-500">or sign up with</span>
|
||||
<span className="h-px bg-gray-400 w-14" />
|
||||
</span>
|
||||
<div className="flex items-center justify-center gap-4">
|
||||
<TwitterButton onClick={signInWithTwitter} />
|
||||
<GoogleButton onClick={signInWithGoogle} />
|
||||
<FacebookButton onClick={signInWithFacebook} />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignupPage;
|
||||
|
||||
4
web/src/lib/util/validationUtils.ts
Normal file
4
web/src/lib/util/validationUtils.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
const validateEmail = (email: string) =>
|
||||
/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(email);
|
||||
|
||||
export { validateEmail };
|
||||
@@ -5,7 +5,7 @@ import { firebaseConfig } from "@/lib/db";
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
|
||||
res.status(StatusCodes.OK).json(firebaseConfig);
|
||||
res.status(StatusCodes.OK).json(process.env);
|
||||
res.end();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user