More auth related sentry whitelist errors (#27481)

* More auth related sentry whitelist errors

* Make pretty
This commit is contained in:
Joshen Lim authored and GitHub committed 2024-06-24 14:29:12 +08:00
1 parent 45066f6b65
commit d80befbae2
6 files changed
+61 -51

No files matched your search

@@ -1,5 +1,4 @@
import HCaptcha from '@hcaptcha/react-hcaptcha'
import * as Sentry from '@sentry/nextjs'
import { useRouter } from 'next/router'
import { useRef, useState } from 'react'
import toast from 'react-hot-toast'
@@ -9,8 +8,6 @@ import { useResetPasswordMutation } from 'data/misc/reset-password-mutation'
import { BASE_PATH } from 'lib/constants'
import { Button, Form, Input } from 'ui'
const WHITELIST_ERRORS = ['email must be an email']
const forgotPasswordSchema = object({
email: string().email('Must be a valid email').required('Email is required'),
})
@@ -31,10 +28,6 @@ const ForgotPasswordForm = () => {
setCaptchaToken(null)
captchaRef.current?.resetCaptcha()
toast.error(`Failed to send reset email: ${error.message}`)
if (!WHITELIST_ERRORS.some((e) => error.message.includes(e))) {
Sentry.captureMessage('[CRITICAL] Failed to send reset password email: ' + error.message)
}
},
})
@@ -1,12 +1,10 @@
import type { AuthError } from '@supabase/auth-js'
import type { Factor } from '@supabase/supabase-js'
import { useQueryClient } from '@tanstack/react-query'
import { Lock } from 'lucide-react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import toast from 'react-hot-toast'
import { object, string } from 'yup'
import * as Sentry from '@sentry/nextjs'
import { useTelemetryProps } from 'common'
import AlertError from 'components/ui/AlertError'
@@ -16,7 +14,7 @@ import { useMfaListFactorsQuery } from 'data/profile/mfa-list-factors-query'
import { useSignOut } from 'lib/auth'
import { getReturnToPath } from 'lib/gotrue'
import Telemetry from 'lib/telemetry'
import { Button, Form, IconLock, Input } from 'ui'
import { Button, Form, Input } from 'ui'
const signInSchema = object({
code: string().required('MFA Code is required'),
@@ -36,7 +34,21 @@ const SignInMfaForm = () => {
isSuccess: isSuccessFactors,
isLoading: isLoadingFactors,
} = useMfaListFactorsQuery()
const { mutate: mfaChallengeAndVerify, isLoading, isSuccess } = useMfaChallengeAndVerifyMutation()
const {
mutate: mfaChallengeAndVerify,
isLoading: isVerifying,
isSuccess,
} = useMfaChallengeAndVerifyMutation({
onSuccess: async () => {
Telemetry.sendEvent(
{ category: 'account', action: 'sign_in', label: '' },
telemetryProps,
router
)
await queryClient.resetQueries()
router.push(getReturnToPath())
},
})
const onClickLogout = async () => {
await signOut()
@@ -44,27 +56,8 @@ const SignInMfaForm = () => {
}
const onSignIn = async ({ code }: { code: string }) => {
const toastId = toast.loading('Signing in...')
if (selectedFactor) {
mfaChallengeAndVerify(
{ factorId: selectedFactor.id, code, refreshFactors: false },
{
onSuccess: async () => {
toast.success('Signed in successfully!', { id: toastId })
Telemetry.sendEvent(
{ category: 'account', action: 'sign_in', label: '' },
telemetryProps,
router
)
await queryClient.resetQueries()
router.push(getReturnToPath())
},
onError: (error) => {
toast.error(`Failed to sign in: ${(error as AuthError).message}`, { id: toastId })
Sentry.captureMessage('[CRITICAL] Failed to sign in via MFA: ' + error.message)
},
}
)
mfaChallengeAndVerify({ factorId: selectedFactor.id, code, refreshFactors: false })
}
}
@@ -102,9 +95,9 @@ const SignInMfaForm = () => {
name="code"
type="text"
autoFocus
icon={<IconLock />}
icon={<Lock />}
placeholder="XXXXXX"
disabled={isLoading}
disabled={isVerifying}
autoComplete="off"
spellCheck="false"
autoCapitalize="none"
@@ -121,7 +114,7 @@ const SignInMfaForm = () => {
block
type="outline"
size="large"
disabled={isLoading || isSuccess}
disabled={isVerifying || isSuccess}
onClick={onClickLogout}
className="opacity-80 hover:opacity-100 transition"
>
@@ -132,10 +125,10 @@ const SignInMfaForm = () => {
form="sign-in-mfa-form"
htmlType="submit"
size="large"
disabled={isLoading || isSuccess}
loading={isLoading || isSuccess}
disabled={isVerifying || isSuccess}
loading={isVerifying || isSuccess}
>
{isLoading ? 'Verifying' : isSuccess ? 'Signing in' : 'Verify'}
{isVerifying ? 'Verifying' : isSuccess ? 'Signing in' : 'Verify'}
</Button>
</div>
</div>
@@ -163,9 +156,9 @@ const SignInMfaForm = () => {
)}
<li>
<Link
href="/support/new?subject=Unable+to+sign+in+via+MFA&category=Login_issues"
target="_blank"
rel="noreferrer"
href="/support/new?subject=Unable+to+sign+in+via+MFA&category=Login_issues"
className="text-sm transition text-foreground-light hover:text-foreground"
>
Reach out to us via support
@@ -1,9 +1,8 @@
import HCaptcha from '@hcaptcha/react-hcaptcha'
import { CheckCircle } from 'lucide-react'
import { CheckCircle, Eye, EyeOff } from 'lucide-react'
import { useRef, useState } from 'react'
import toast from 'react-hot-toast'
import * as yup from 'yup'
import * as Sentry from '@sentry/nextjs'
import { useSignUpMutation } from 'data/misc/signup-mutation'
import { BASE_PATH } from 'lib/constants'
@@ -14,14 +13,10 @@ import {
Alert_Shadcn_,
Button,
Form,
IconEye,
IconEyeOff,
Input,
} from 'ui'
import PasswordConditionsHelper from './PasswordConditionsHelper'
const WHITELIST_ERRORS = ['A user with this email already exists']
const signUpSchema = passwordSchema.shape({
email: yup.string().email().required().label('Email'),
})
@@ -42,10 +37,6 @@ const SignUpForm = () => {
setCaptchaToken(null)
captchaRef.current?.resetCaptcha()
toast.error(`Failed to sign up: ${error.message}`)
if (!WHITELIST_ERRORS.includes(error.message)) {
Sentry.captureMessage('[CRITICAL] Failed to sign up: ' + error.message)
}
},
})
@@ -118,7 +109,7 @@ const SignUpForm = () => {
onFocus={() => setShowConditions(true)}
actions={
<Button
icon={passwordHidden ? <IconEye /> : <IconEyeOff />}
icon={passwordHidden ? <Eye /> : <EyeOff />}
type="default"
className="!mr-1"
onClick={() => setPasswordHidden((prev) => !prev)}
@@ -1,9 +1,12 @@
import * as Sentry from '@sentry/nextjs'
import { useMutation, UseMutationOptions } from '@tanstack/react-query'
import { toast } from 'react-hot-toast'
import { handleError, post } from 'data/fetchers'
import type { ResponseError } from 'types'
const WHITELIST_ERRORS = ['email must be an email']
export type ResetPasswordVariables = {
email: string
hcaptchaToken: string | null
@@ -42,6 +45,9 @@ export const useResetPasswordMutation = ({
} else {
onError(data, variables, context)
}
if (!WHITELIST_ERRORS.some((error) => data.message.includes(error))) {
Sentry.captureMessage('[CRITICAL] Failed to send reset password email: ' + data.message)
}
},
...options,
}
+11
View File
@@ -1,9 +1,17 @@
import * as Sentry from '@sentry/nextjs'
import { useMutation, UseMutationOptions } from '@tanstack/react-query'
import { toast } from 'react-hot-toast'
import { handleError, post } from 'data/fetchers'
import type { ResponseError } from 'types'
const WHITELIST_ERRORS = [
'A user with this email already exists',
'Password should contain at least one character of each',
'You attempted to send email to an inactive recipient',
'email must be an email',
]
export type SignUpVariables = {
email: string
password: string
@@ -38,6 +46,9 @@ export const useSignUpMutation = ({
} else {
onError(data, variables, context)
}
if (!WHITELIST_ERRORS.some((error) => data.message.includes(error))) {
Sentry.captureMessage('[CRITICAL] Failed to sign up: ' + data.message)
}
},
...options,
})
@@ -1,8 +1,13 @@
import * as Sentry from '@sentry/nextjs'
import type { AuthMFAVerifyResponse, MFAChallengeAndVerifyParams } from '@supabase/supabase-js'
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import { UseMutationOptions, useMutation, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'
import { auth } from 'lib/gotrue'
import { profileKeys } from './keys'
const WHITELIST_ERRORS = ['Invalid TOTP code entered']
interface MFAChallengeAndVerifyVariables extends MFAChallengeAndVerifyParams {
refreshFactors?: boolean
}
@@ -18,6 +23,7 @@ type CustomMFAVerifyError = NonNullable<AuthMFAVerifyResponse['error']>
export const useMfaChallengeAndVerifyMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseMutationOptions<CustomMFAVerifyResponse, CustomMFAVerifyError, MFAChallengeAndVerifyVariables>,
@@ -42,6 +48,16 @@ export const useMfaChallengeAndVerifyMutation = ({
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to sign in: ${data.message}`)
} else {
onError(data, variables, context)
}
if (!WHITELIST_ERRORS.some((error) => data.message.includes(error))) {
Sentry.captureMessage('[CRITICAL] Failed to sign in via MFA: ' + data.message)
}
},
...options,
}
)