Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions app/api/auth/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ const supabase = createClient(

export async function POST(req) {
try {
const { email, password, captchaToken, action } = await req.json()
// Parse JSON body safely
const body = await req.json()
const { email, password, captchaToken, action } = body || {}

if (!email || !password)
return new Response(JSON.stringify({ message: 'Email and password required' }), { status: 400 })
// Validate required fields
if (!email || !password) {
return new Response(JSON.stringify({ success: false, message: 'Email and password are required' }), { status: 400 })
}

if (action === 'signup') {
if (!captchaToken)
return new Response(JSON.stringify({ message: 'Captcha token missing' }), { status: 400 })
if (!captchaToken) {
return new Response(JSON.stringify({ success: false, message: 'Captcha token missing' }), { status: 400 })
}

// Verify Turnstile token
const verifyRes = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
Expand All @@ -26,27 +31,32 @@ export async function POST(req) {
}),
})

const data = await verifyRes.json()
if (!data.success)
return new Response(JSON.stringify({ message: 'Captcha verification failed' }), { status: 400 })
const verifyData = await verifyRes.json()
if (!verifyData.success) {
return new Response(JSON.stringify({ success: false, message: 'Captcha verification failed' }), { status: 400 })
}

// Create Supabase user
const { user, error } = await supabase.auth.admin.createUser({ email, password })
if (error)
return new Response(JSON.stringify({ message: error.message }), { status: 400 })
if (error) {
return new Response(JSON.stringify({ success: false, message: error.message }), { status: 400 })
}

return new Response(JSON.stringify({ message: 'Signup successful! Check your email.' }), { status: 200 })
return new Response(JSON.stringify({ success: true, message: 'Signup successful! Check your email.' }), { status: 200 })
}

// Login stays frontend-only
else if (action === 'login') {
return new Response(JSON.stringify({ message: 'Use frontend login with anon key' }), { status: 400 })
return new Response(JSON.stringify({ success: false, message: 'Use frontend login with anon key' }), { status: 400 })
}

// Invalid action
else {
return new Response(JSON.stringify({ message: 'Invalid action' }), { status: 400 })
return new Response(JSON.stringify({ success: false, message: 'Invalid action' }), { status: 400 })
}

} catch (err) {
console.error(err)
return new Response(JSON.stringify({ message: 'Internal server error' }), { status: 500 })
console.error('API Error:', err)
return new Response(JSON.stringify({ success: false, message: 'Internal server error' }), { status: 500 })
}
}
10 changes: 6 additions & 4 deletions app/login/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default function LoginPage() {

try {
if (isLogin) {
// Login with frontend anon key
// Login using frontend anon key only, no captcha
const { error } = await supabase.auth.signInWithPassword({ email, password })
if (error) throw error
router.push('/dashboard')
Expand All @@ -56,13 +56,13 @@ export default function LoginPage() {
})

const data = await res.json()
if (!res.ok) throw new Error(data.message)
if (!data.success) throw new Error(data.message || 'Signup failed')

alert(data.message)
setIsLogin(true) // switch to login after signup
}
} catch (err) {
setError(err.message)
setError(err.message || 'Something went wrong')
} finally {
setLoading(false)
}
Expand Down Expand Up @@ -141,6 +141,7 @@ export default function LoginPage() {
</div>
)}

{/* Turnstile only for signup */}
{!isLogin && (
<div className="flex justify-center">
<Turnstile
Expand Down Expand Up @@ -203,7 +204,8 @@ export default function LoginPage() {
onClick={handleGoogleSignIn}
className="w-full flex items-center justify-center py-3 px-4 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200 font-medium hover:bg-gray-50 dark:hover:bg-gray-600 transition-all"
>
Continue with Google
<img src="./google.webp" width={24}></img>
<span className='mx-2'>Continue with Google</span>
</button>

<div className="text-center text-xs text-gray-500 dark:text-gray-400 mt-6">
Expand Down
Binary file added public/google.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading