Todo list updated

cgen-7dee112ec2a44f7eba17438c4a8b4675
This commit is contained in:
Builder.io 2025-11-05 03:44:40 +00:00
parent 83e8081a70
commit 2df17dc8ec
2 changed files with 89 additions and 12 deletions

View file

@ -553,15 +553,53 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
if (error) throw error;
// Supabase sends the confirmation email automatically (SMTP or default provider)
let emailSent = true;
// Send verification email via custom SMTP (fallback: Supabase auth email)
let emailSent = false;
let verificationUrl: string | undefined;
if (data.user) {
aethexToast.success({
title: "Verify your email",
description: `We sent a confirmation to ${email}.`,
});
try {
// Try to send via custom SMTP server
const verifyResponse = await fetch("/api/auth/send-verification-email", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email,
redirectTo,
fullName: metadata.full_name || null,
}),
});
const verifyPayload = await verifyResponse.json().catch(() => ({}));
if (verifyResponse.ok && verifyPayload?.sent) {
emailSent = true;
aethexToast.success({
title: "Verify your email",
description: `We sent a confirmation to ${email}.`,
});
} else {
// Custom SMTP failed, but provide manual link if available
verificationUrl = verifyPayload?.verificationUrl || undefined;
if (verificationUrl) {
aethexToast.warning({
title: "Verify your email",
description: `We couldn't send the email automatically. Use the manual verification link in your account settings.`,
});
} else {
aethexToast.info({
title: "Account created",
description: `Please check your email to verify your account.`,
});
}
}
} catch (emailErr) {
console.warn("[Auth] Failed to send verification email:", emailErr);
aethexToast.info({
title: "Account created",
description: `Please check your email to verify your account.`,
});
}
}
return { emailSent, verificationUrl } as const;

View file

@ -536,23 +536,62 @@ export function createServer() {
app.post("/api/posts", async (req, res) => {
const payload = req.body || {};
// Validation
if (!payload.author_id) {
return res.status(400).json({ error: "author_id is required" });
}
if (!payload.title || typeof payload.title !== "string" || !payload.title.trim()) {
return res.status(400).json({ error: "title is required and must be a non-empty string" });
}
if (!payload.content || typeof payload.content !== "string" || !payload.content.trim()) {
return res.status(400).json({ error: "content is required and must be a non-empty string" });
}
// Validate author_id is a valid UUID format
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!uuidRegex.test(String(payload.author_id))) {
return res.status(400).json({ error: "author_id must be a valid UUID" });
}
try {
// Verify author exists
const { data: author, error: authorError } = await adminSupabase
.from("user_profiles")
.select("id")
.eq("id", payload.author_id)
.single();
if (authorError || !author) {
return res.status(404).json({ error: "Author not found" });
}
const { data, error } = await adminSupabase
.from("community_posts")
.insert({
author_id: payload.author_id,
title: payload.title,
content: payload.content,
category: payload.category,
tags: payload.tags,
title: String(payload.title).trim(),
content: String(payload.content).trim(),
category: payload.category ? String(payload.category).trim() : null,
tags: Array.isArray(payload.tags) ? payload.tags.map((t: any) => String(t).trim()) : [],
is_published: payload.is_published ?? true,
})
.select()
.single();
if (error) return res.status(500).json({ error: error.message });
if (error) {
console.error("[API] /api/posts insert error:", {
code: error.code,
message: error.message,
details: (error as any).details,
});
return res.status(500).json({ error: error.message || "Failed to create post" });
}
res.json(data);
} catch (e: any) {
res.status(500).json({ error: e?.message || String(e) });
console.error("[API] /api/posts exception:", e?.message || String(e));
res.status(500).json({ error: e?.message || "Failed to create post" });
}
});