diff --git a/site/components/Signin.tsx b/site/components/Signin.tsx index 3155a588c..b48e1655d 100644 --- a/site/components/Signin.tsx +++ b/site/components/Signin.tsx @@ -5,6 +5,7 @@ import { useSearchParams, useRouter } from 'next/navigation'; import Icon from '@/components/Icon'; import { signIn } from 'next-auth/react'; import { ChangeEvent, useState } from 'react'; +import { getNextAuthErrorMessage } from '@/helpers/index'; export default function Signin() { const router = useRouter(); @@ -14,8 +15,8 @@ export default function Signin() { email: '', password: '', }); - const [error, setError] = useState(searchParams.get('error') || ''); - + const nextAuthError = searchParams.get('error'); + const [error, setError] = useState(nextAuthError ? getNextAuthErrorMessage(nextAuthError) : ''); const callbackUrl = searchParams.get('callbackUrl') || '/'; const onSubmit = async (e: React.FormEvent) => { @@ -36,7 +37,7 @@ export default function Signin() { if (!res?.error) { router.push(callbackUrl); } else { - setError('invalid email or password'); + setError('Invalid email or password'); } } catch (error: any) { setLoading(false); diff --git a/site/helpers/index.ts b/site/helpers/index.ts index e145eb500..9adf46e7d 100644 --- a/site/helpers/index.ts +++ b/site/helpers/index.ts @@ -1,40 +1,75 @@ export const groupBy = function (xs, key) { return xs.reduce(function (rv, x) { - ;(rv[x[key]] = rv[x[key]] || []).push(x) - return rv - }, {}) -} + ;(rv[x[key]] = rv[x[key]] || []).push(x); + return rv; + }, {}); +}; export const sortByKeys = function (xs) { return Object.keys(xs) .sort() .reduce((obj, key) => { - obj[key] = xs[key] - return obj - }, {}) -} + obj[key] = xs[key]; + return obj; + }, {}); +}; export const toPascalCase = function (text: string) { return text - .replace(new RegExp(/[-_]+/, "g"), " ") - .replace(new RegExp(/[^\w\s]/, "g"), "") + .replace(new RegExp(/[-_]+/, 'g'), ' ') + .replace(new RegExp(/[^\w\s]/, 'g'), '') .replace( - new RegExp(/\s+(.)(\w+)/, "g"), + new RegExp(/\s+(.)(\w+)/, 'g'), ($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}` ) - .replace(new RegExp(/\s/, "g"), "") - .replace(new RegExp(/\w/), (s) => s.toUpperCase()) -} + .replace(new RegExp(/\s/, 'g'), '') + .replace(new RegExp(/\w/), (s) => s.toUpperCase()); +}; export const baseUrl = { - development: "http://localhost:3000", - production: "https://tabler-icons.io", -}[process.env.NODE_ENV] + development: 'http://localhost:3000', + production: 'https://tabler-icons.io', +}[process.env.NODE_ENV]; export const getCurrentBrand = (hostname: string) => { if (hostname && hostname.match(/tabler-icons/)) { - return "tabler-icons" + return 'tabler-icons'; } - return "tabler-ui" -} + return 'tabler-ui'; +}; + +export const getNextAuthErrorMessage = (error: string): string => { + // Nextauth errors + // https://next-auth.js.org/configuration/pages#sign-in-page + // OAuthSignin: Error in constructing an authorization URL (1, 2, 3), + // OAuthCallback: Error in handling the response (1, 2, 3) from an OAuth provider. + // OAuthCreateAccount: Could not create OAuth provider user in the database. + // EmailCreateAccount: Could not create email provider user in the database. + // Callback: Error in the OAuth callback handler route + // OAuthAccountNotLinked: If the email on the account is already linked, but not with this OAuth account + // EmailSignin: Sending the e-mail with the verification token failed + // CredentialsSignin: The authorize callback returned null in the Credentials provider. We don't recommend providing information about which part of the credentials were wrong, as it might be abused by malicious hackers. + // SessionRequired: The content of this page requires you to be signed in at all times. See useSession for configuration. + // Default: Catch all, will apply, if none of the above matched + + switch (error) { + case 'OAuthSignin': + case 'OAuthCallback': + case 'OAuthCreateAccount': + case 'EmailCreateAccount': + case 'Callback': + return 'Try signing in with a different account.'; + case 'OAuthAccountNotLinked': + return 'To confirm your identity, sign in with the same account you used originally.'; + case 'EmailSignin': + return 'The e-mail could not be sent.'; + case 'CredentialsSignin': + return 'Sign in failed. Check the details you provided are correct.'; + case 'SessionRequired': + return 'Please sign in to access this page.'; + case 'Default': + default: + return 'Unable to sign in.'; + } +}; \ No newline at end of file