import type { SupabaseClient, User } from "@supabase/supabase-js"; import { Hono } from "hono"; import type { Transporter } from "nodemailer"; import { StreamChat } from "stream-chat"; import type { Tables } from "./database.types.ts"; import { authMiddleware, streamChatMiddleware } from "./middleware.js"; import { transporter } from "./transporter.js"; export const userRouter = new Hono<{ Variables: { user: User; supabase: SupabaseClient; transporter: Transporter; streamServerClient: StreamChat; }; }>(); userRouter.use(authMiddleware); userRouter.use(streamChatMiddleware); userRouter.post("/sign-up-to-stream", async (c) => { const { id } = c.get("user"); const supabase = c.get("supabase"); const { data } = await supabase .from("profiles") .select("*") .eq("id", id) .single(); const user = data as Tables<"profiles">; const streamServerClient = c.get("streamServerClient"); await streamServerClient.upsertUser({ id, name: user.name ?? "", language: "fr", }); return c.json({ message: "User signed up to stream", }); }); userRouter.get("/me", async (c) => { const user = c.get("user"); const supabase = c.get("supabase"); const streamServerClient = c.get("streamServerClient"); const { data, error } = await supabase .from("profiles") .select("*") .eq("id", user.id) .single(); const userData = data as Tables<"profiles">; if (!userData) { return c.json({ error: "User not found" }, 404); } if (error) { return c.json({ error: error.message }, 500); } const user_id = data.id; const token = streamServerClient.createToken(user_id); return c.json({ ...userData, streamToken: token, }); }); userRouter.post("/mark-temporary", async (c) => { const user = c.get("user"); const supabase = c.get("supabase"); const body = await c.req.json(); const { temporary_password } = body; const { data: profile, error } = await supabase .from("profiles") .update({ is_temporary: true, }) .eq("id", user.id) .select() .single(); if (error) { return c.json({ error: error.message }, 500); } try { if (profile?.email && transporter) { const mailOptions = { from: "Xtablo ", to: profile.email, subject: "Bienvenue sur XTablo - Votre mot de passe temporaire", text: `Bienvenue sur XTablo ! Votre compte a été créé avec succès. Voici vos informations de connexion : Email : ${profile.email} Mot de passe temporaire : ${temporary_password} Pour des raisons de sécurité, nous vous recommandons fortement de changer ce mot de passe temporaire lors de votre première connexion. Connectez-vous sur : ${process.env.FRONTEND_URL || "https://app.xtablo.com"} Cordialement, L'équipe XTablo`, html: `

Bienvenue sur XTablo !

Votre compte a été créé avec succès. Voici vos informations de connexion :

Email : ${profile.email}

Mot de passe temporaire : ${temporary_password}

Important : Pour des raisons de sécurité, nous vous recommandons fortement de changer ce mot de passe temporaire lors de votre première connexion.

Se connecter à XTablo

Cordialement,
L'équipe XTablo

`, }; await transporter.sendMail(mailOptions); } } catch (error) { console.error("Failed to send welcome email:", error); } return c.json({ message: "User marked as temporary", }); }); userRouter.put("/profile", async (c) => { const user = c.get("user"); const supabase = c.get("supabase"); const body = await c.req.json(); const { first_name, last_name, introduction_email } = body; // Combine first_name and last_name into a single name field const name = [first_name, last_name].filter(Boolean).join(" "); const { data: profile, error } = await supabase .from("profiles") .update({ name: name || null, first_name: first_name || null, last_name: last_name || null, }) .eq("id", user.id) .select() .single(); if (error) { return c.json({ error: error.message }, 500); } // Update user metadata in Supabase Auth using updateUser const { error: authError } = await supabase.auth.updateUser({ data: { first_name: first_name || "", last_name: last_name || "", introduction_email: introduction_email || "", }, }); if (authError) { console.error("Failed to update user metadata:", authError); // Don't fail the request if metadata update fails } return c.json({ message: "Profile updated successfully", profile, }); });