migrate auth from next-auth to better-auth with magic link support

Replace next-auth with better-auth, adding magic link email login as
the primary auth method and GitHub OAuth as an optional social provider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Thomas Ruoff
2026-03-03 21:07:23 +01:00
parent bc34a05d2b
commit d63ded8c6a
11 changed files with 1506 additions and 427 deletions

View File

@@ -1,21 +1,42 @@
import { useEffect } from 'react'
import { useSession, signIn } from 'next-auth/react'
import { useState } from 'react'
import { useSession, signIn } from '../lib/auth-client'
import Input from './input'
import Button from './button'
export default function Auth({ children }) {
const { data: session, status } = useSession()
const { data: session, isPending } = useSession()
const isUser = !!session?.user
const [email, setEmail] = useState('')
const [loading, setLoading] = useState(false)
const [sent, setSent] = useState(false)
const [error, setError] = useState('')
useEffect(() => {
if (status === 'loading') return // Do nothing while loading
if (!isUser) signIn() // If not authenticated, force log in
}, [isUser, status])
if (isPending) return <div>Loading...</div>
if (isUser) {
return children
if (isUser) return children
if (process.env.NEXT_PUBLIC_GITHUB_ENABLED) {
signIn.social({ provider: "github", callbackURL: window.location.href })
return <div>Loading...</div>
}
// Session is being fetched, or no user.
// If no user, useEffect() will redirect.
return <div>Loading...</div>
if (sent) return <div>E-Mail verschickt bitte prüfe dein Postfach.</div>
async function handleSubmit(e: React.FormEvent) {
e.preventDefault()
setLoading(true)
setError('')
const result = await signIn.magicLink({ email, callbackURL: window.location.href })
if (result.error) setError(result.error.message)
else setSent(true)
setLoading(false)
}
return (
<form onSubmit={handleSubmit} className="max-w-sm mx-auto mt-16">
<Input label="E-Mail" name="email" type="email" value={email} onChange={e => setEmail(e.target.value)} required />
{error && <p className="text-red-500 text-sm mb-3">{error}</p>}
<Button type="submit" loading={loading}>Magic Link senden</Button>
</form>
)
}