Skip to content

Commit

Permalink
feat: pass auth confirmation error as query param and show in UI (#23)
Browse files Browse the repository at this point in the history
Co-authored-by: iamhectorsosa <hello@hectorsosa.me>
  • Loading branch information
rudokotrla and iamhectorsosa authored Apr 26, 2024
1 parent 6471ca2 commit ea4c378
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 11 deletions.
15 changes: 9 additions & 6 deletions apps/next/app/auth/confirm/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export async function GET(request: NextRequest) {

const redirectTo = request.nextUrl.clone()
redirectTo.pathname = next
redirectTo.searchParams.delete("next")
redirectTo.searchParams.delete("token_hash")
redirectTo.searchParams.delete("type")

Expand All @@ -22,12 +23,14 @@ export async function GET(request: NextRequest) {
token_hash,
})

if (!error) {
redirectTo.searchParams.delete("next")
return NextResponse.redirect(redirectTo)
if (error) {
redirectTo.pathname = "/login"
redirectTo.searchParams.set(
"error",
JSON.stringify({ message: error.message, status: error.status || 401 })
)
}
}

redirectTo.pathname = "/"
return NextResponse.redirect(redirectTo)
return NextResponse.redirect(redirectTo)
}
}
24 changes: 23 additions & 1 deletion apps/next/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { redirect } from "next/navigation"
import { z } from "zod"

import { LoginForm } from "@/components/user/login-form"

import { createClient } from "@/modules/utils/server"

export default async function Page() {
export default async function Page({
searchParams: { error },
}: {
searchParams: { error?: string }
}) {
const supabase = createClient()

const {
Expand All @@ -15,5 +20,22 @@ export default async function Page() {
redirect("/settings/accounts")
}

if (error) {
return <LoginForm error={parseError(error)} />
}

return <LoginForm />
}

const errorSchema = z.object({
message: z.string().catch("An error occurred"),
status: z.number().catch(500),
})

function parseError(error: string) {
try {
return errorSchema.parse(JSON.parse(error))
} catch (_error) {
return errorSchema.parse({})
}
}
42 changes: 38 additions & 4 deletions apps/next/components/user/login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,38 @@ import { Switch } from "@/components/ui/switch"

import { signInWithEmailPassword, signInWithOtp } from "@/modules/user/auth"

export const LoginForm: React.FC = () => {
type SearchParamError = {
message: string
status: number
}

function getErrorProps({
error,
searchParamError,
}: {
error: Error | null
searchParamError: SearchParamError | null
}) {
if (error) {
const digest = getDigest(error)
return {
isError: true,
errorMessage: `Log in was not successful, please try again; ref: ${digest}`,
}
} else if (searchParamError) {
return {
isError: true,
errorMessage: searchParamError.message,
}
}
return {
isError: false,
}
}

export const LoginForm: React.FC<{
error?: SearchParamError
}> = ({ error }) => {
const signIn = useMutation({
mutationFn: signInWithEmailPassword,
})
Expand Down Expand Up @@ -65,14 +96,17 @@ export const LoginForm: React.FC = () => {
})
}

const digest = getDigest(signIn.error) ?? getDigest(passwordlessSignIn.error)
const { isError, errorMessage } = getErrorProps({
error: signIn.error || passwordlessSignIn.error,
searchParamError: error || null,
})

return (
<LoginFormComponent
signIn={handleSignIn}
isPending={signIn.isPending || passwordlessSignIn.isPending}
isError={signIn.isError || passwordlessSignIn.isError}
errorMessage={`Log in was not successful, please try again; ref: ${digest}`}
isError={isError}
errorMessage={errorMessage}
/>
)
}
Expand Down

0 comments on commit ea4c378

Please sign in to comment.