chore: bump version to 2.21.6 in package.json and enhance captcha integration across auth components (#418)
- Updated application version from 2.21.4 to 2.21.6 in package.json. - Added "verifyingCaptcha" message to auth.json for improved user feedback during captcha verification. - Enhanced captcha handling in various authentication components, including MagicLinkAuthContainer, PasswordResetRequestContainer, and SignUpContainer, to reflect loading states and improve user experience.
This commit is contained in:
committed by
GitHub
parent
a78da16790
commit
f6c635aac3
@@ -10,6 +10,7 @@
|
|||||||
"signOut": "Sign out",
|
"signOut": "Sign out",
|
||||||
"signingIn": "Signing in...",
|
"signingIn": "Signing in...",
|
||||||
"signingUp": "Signing up...",
|
"signingUp": "Signing up...",
|
||||||
|
"verifyingCaptcha": "Verifying...",
|
||||||
"doNotHaveAccountYet": "Do not have an account yet?",
|
"doNotHaveAccountYet": "Do not have an account yet?",
|
||||||
"alreadyHaveAnAccount": "Already have an account?",
|
"alreadyHaveAnAccount": "Already have an account?",
|
||||||
"signUpToAcceptInvite": "Please sign in/up to accept the invite",
|
"signUpToAcceptInvite": "Please sign in/up to accept the invite",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "next-supabase-saas-kit-turbo",
|
"name": "next-supabase-saas-kit-turbo",
|
||||||
"version": "2.21.4",
|
"version": "2.21.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -67,15 +67,20 @@ export function useCaptcha(
|
|||||||
[siteKey, nonce, handleTokenChange, handleInstanceChange],
|
[siteKey, nonce, handleTokenChange, handleInstanceChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Ready when captcha is not configured (no siteKey) or token is available
|
||||||
|
const isReady = !siteKey || token !== '';
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
/** The current captcha token */
|
/** The current captcha token */
|
||||||
token,
|
token,
|
||||||
|
/** Whether the captcha is ready (not configured or token available) */
|
||||||
|
isReady,
|
||||||
/** Reset the captcha (clears token and resets widget) */
|
/** Reset the captcha (clears token and resets widget) */
|
||||||
reset,
|
reset,
|
||||||
/** The captcha field component to render */
|
/** The captcha field component to render */
|
||||||
field,
|
field,
|
||||||
}),
|
}),
|
||||||
[token, reset, field],
|
[token, isReady, reset, field],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ export function MagicLinkAuthContainer({
|
|||||||
const appEvents = useAppEvents();
|
const appEvents = useAppEvents();
|
||||||
const { recordAuthMethod } = useLastAuthMethod();
|
const { recordAuthMethod } = useLastAuthMethod();
|
||||||
|
|
||||||
|
const captchaLoading = !captcha.isReady;
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
resolver: zodResolver(
|
resolver: zodResolver(
|
||||||
z.object({
|
z.object({
|
||||||
@@ -131,13 +133,18 @@ export function MagicLinkAuthContainer({
|
|||||||
<TermsAndConditionsFormField />
|
<TermsAndConditionsFormField />
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<Button disabled={signInWithOtpMutation.isPending}>
|
<Button disabled={signInWithOtpMutation.isPending || captchaLoading}>
|
||||||
<If
|
<If condition={captchaLoading}>
|
||||||
condition={signInWithOtpMutation.isPending}
|
<Trans i18nKey={'auth:verifyingCaptcha'} />
|
||||||
fallback={<Trans i18nKey={'auth:sendEmailLink'} />}
|
</If>
|
||||||
>
|
|
||||||
|
<If condition={signInWithOtpMutation.isPending && !captchaLoading}>
|
||||||
<Trans i18nKey={'auth:sendingEmailLink'} />
|
<Trans i18nKey={'auth:sendingEmailLink'} />
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
<If condition={!signInWithOtpMutation.isPending && !captchaLoading}>
|
||||||
|
<Trans i18nKey={'auth:sendEmailLink'} />
|
||||||
|
</If>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export function PasswordResetRequestContainer(params: {
|
|||||||
const { t } = useTranslation('auth');
|
const { t } = useTranslation('auth');
|
||||||
const resetPasswordMutation = useRequestResetPassword();
|
const resetPasswordMutation = useRequestResetPassword();
|
||||||
const captcha = useCaptcha({ siteKey: params.captchaSiteKey });
|
const captcha = useCaptcha({ siteKey: params.captchaSiteKey });
|
||||||
|
const captchaLoading = !captcha.isReady;
|
||||||
|
|
||||||
const error = resetPasswordMutation.error;
|
const error = resetPasswordMutation.error;
|
||||||
const success = resetPasswordMutation.data;
|
const success = resetPasswordMutation.data;
|
||||||
@@ -101,8 +102,16 @@ export function PasswordResetRequestContainer(params: {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button disabled={resetPasswordMutation.isPending} type="submit">
|
<Button
|
||||||
<Trans i18nKey={'auth:passwordResetLabel'} />
|
disabled={resetPasswordMutation.isPending || captchaLoading}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<If
|
||||||
|
condition={captchaLoading}
|
||||||
|
fallback={<Trans i18nKey={'auth:passwordResetLabel'} />}
|
||||||
|
>
|
||||||
|
<Trans i18nKey={'auth:verifyingCaptcha'} />
|
||||||
|
</If>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{captcha.field}
|
{captcha.field}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export function PasswordSignInContainer({
|
|||||||
const { recordAuthMethod } = useLastAuthMethod();
|
const { recordAuthMethod } = useLastAuthMethod();
|
||||||
const isLoading = signInMutation.isPending;
|
const isLoading = signInMutation.isPending;
|
||||||
const isRedirecting = signInMutation.isSuccess;
|
const isRedirecting = signInMutation.isSuccess;
|
||||||
|
const captchaLoading = !captcha.isReady;
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
async (credentials: z.infer<typeof PasswordSignInSchema>) => {
|
async (credentials: z.infer<typeof PasswordSignInSchema>) => {
|
||||||
@@ -59,6 +60,7 @@ export function PasswordSignInContainer({
|
|||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
redirecting={isRedirecting}
|
redirecting={isRedirecting}
|
||||||
|
captchaLoading={captchaLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{captcha.field}
|
{captcha.field}
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ import { PasswordInput } from './password-input';
|
|||||||
|
|
||||||
export function PasswordSignInForm({
|
export function PasswordSignInForm({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
captchaLoading = false,
|
||||||
loading = false,
|
loading = false,
|
||||||
redirecting = false,
|
redirecting = false,
|
||||||
}: {
|
}: {
|
||||||
onSubmit: (params: z.infer<typeof PasswordSignInSchema>) => unknown;
|
onSubmit: (params: z.infer<typeof PasswordSignInSchema>) => unknown;
|
||||||
|
captchaLoading: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
redirecting: boolean;
|
redirecting: boolean;
|
||||||
}) {
|
}) {
|
||||||
@@ -126,6 +128,12 @@ export function PasswordSignInForm({
|
|||||||
</span>
|
</span>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
<If condition={captchaLoading}>
|
||||||
|
<span className={'animate-in fade-in slide-in-from-bottom-24'}>
|
||||||
|
<Trans i18nKey={'auth:verifyingCaptcha'} />
|
||||||
|
</span>
|
||||||
|
</If>
|
||||||
|
|
||||||
<If condition={!redirecting && !loading}>
|
<If condition={!redirecting && !loading}>
|
||||||
<span className={'animate-out fade-out flex items-center'}>
|
<span className={'animate-out fade-out flex items-center'}>
|
||||||
<Trans i18nKey={'auth:signInWithEmail'} />
|
<Trans i18nKey={'auth:signInWithEmail'} />
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export function EmailPasswordSignUpContainer({
|
|||||||
captchaSiteKey,
|
captchaSiteKey,
|
||||||
}: EmailPasswordSignUpContainerProps) {
|
}: EmailPasswordSignUpContainerProps) {
|
||||||
const captcha = useCaptcha({ siteKey: captchaSiteKey });
|
const captcha = useCaptcha({ siteKey: captchaSiteKey });
|
||||||
|
const captchaLoading = !captcha.isReady;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
signUp: onSignupRequested,
|
signUp: onSignupRequested,
|
||||||
@@ -57,6 +58,7 @@ export function EmailPasswordSignUpContainer({
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
displayTermsCheckbox={displayTermsCheckbox}
|
displayTermsCheckbox={displayTermsCheckbox}
|
||||||
|
captchaLoading={captchaLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{captcha.field}
|
{captcha.field}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ interface PasswordSignUpFormProps {
|
|||||||
password: string;
|
password: string;
|
||||||
repeatPassword: string;
|
repeatPassword: string;
|
||||||
}) => unknown;
|
}) => unknown;
|
||||||
|
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
captchaLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PasswordSignUpForm({
|
export function PasswordSignUpForm({
|
||||||
@@ -41,6 +43,7 @@ export function PasswordSignUpForm({
|
|||||||
displayTermsCheckbox,
|
displayTermsCheckbox,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
loading,
|
loading,
|
||||||
|
captchaLoading,
|
||||||
}: PasswordSignUpFormProps) {
|
}: PasswordSignUpFormProps) {
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
resolver: zodResolver(PasswordSignUpSchema),
|
resolver: zodResolver(PasswordSignUpSchema),
|
||||||
@@ -116,11 +119,17 @@ export function PasswordSignUpForm({
|
|||||||
data-test={'auth-submit-button'}
|
data-test={'auth-submit-button'}
|
||||||
className={'w-full'}
|
className={'w-full'}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={loading}
|
disabled={loading || captchaLoading}
|
||||||
>
|
>
|
||||||
<If
|
<If condition={captchaLoading}>
|
||||||
condition={loading}
|
<Trans i18nKey={'auth:verifyingCaptcha'} />
|
||||||
fallback={
|
</If>
|
||||||
|
|
||||||
|
<If condition={loading && !captchaLoading}>
|
||||||
|
<Trans i18nKey={'auth:signingUp'} />
|
||||||
|
</If>
|
||||||
|
|
||||||
|
<If condition={!loading && !captchaLoading}>
|
||||||
<>
|
<>
|
||||||
<Trans i18nKey={'auth:signUpWithEmail'} />
|
<Trans i18nKey={'auth:signUpWithEmail'} />
|
||||||
|
|
||||||
@@ -130,9 +139,6 @@ export function PasswordSignUpForm({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
|
||||||
>
|
|
||||||
<Trans i18nKey={'auth:signingUp'} />
|
|
||||||
</If>
|
</If>
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
FormItem,
|
FormItem,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@kit/ui/form';
|
} from '@kit/ui/form';
|
||||||
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { useCaptcha } from '../captcha/client';
|
import { useCaptcha } from '../captcha/client';
|
||||||
@@ -26,6 +27,7 @@ export function ResendAuthLinkForm(props: {
|
|||||||
}) {
|
}) {
|
||||||
const captcha = useCaptcha({ siteKey: props.captchaSiteKey });
|
const captcha = useCaptcha({ siteKey: props.captchaSiteKey });
|
||||||
const resendLink = useResendLink(captcha.token);
|
const resendLink = useResendLink(captcha.token);
|
||||||
|
const captchaLoading = !captcha.isReady;
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
resolver: zodResolver(z.object({ email: z.string().email() })),
|
resolver: zodResolver(z.object({ email: z.string().email() })),
|
||||||
@@ -83,7 +85,15 @@ export function ResendAuthLinkForm(props: {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button disabled={resendLink.isPending}>
|
<Button disabled={resendLink.isPending || captchaLoading}>
|
||||||
|
<If condition={captchaLoading}>
|
||||||
|
<Trans i18nKey={'auth:verifyingCaptcha'} />
|
||||||
|
</If>
|
||||||
|
|
||||||
|
<If condition={resendLink.isPending && !captchaLoading}>
|
||||||
|
<Trans i18nKey={'auth:resendingLink'} />
|
||||||
|
</If>
|
||||||
|
|
||||||
<Trans i18nKey={'auth:resendLink'} defaults={'Resend Link'} />
|
<Trans i18nKey={'auth:resendLink'} defaults={'Resend Link'} />
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user