Spaces:
Sleeping
Sleeping
"use server"; | |
import { createClient } from "@/utils/supabase/server"; | |
import { createClient as createSupabaseClient } from "@supabase/supabase-js"; | |
export type ForgotResult = | |
| { ok: true; message: string } | |
| { ok: false; message: string }; | |
export async function sendResetEmail(email: string): Promise<ForgotResult> { | |
const supabase = createClient(); | |
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { | |
return { ok: false, message: "Email tidak valid" }; | |
} | |
// Admin-only: verify the email belongs to an admin user before sending reset link | |
try { | |
const adminClient = createSupabaseClient( | |
process.env.NEXT_PUBLIC_SUPABASE_URL!, | |
process.env.SUPABASE_SERVICE_KEY!, | |
); | |
// list users and find by email (no direct getUserByEmail in v2) | |
let page = 1; | |
const perPage = 200; | |
let foundRole: unknown = null; | |
while (true) { | |
const { data, error } = await adminClient.auth.admin.listUsers({ page, perPage }); | |
if (error) throw error; | |
const users = data?.users || []; | |
const match = users.find((u) => u.email?.toLowerCase() === email.toLowerCase()); | |
if (match) { | |
foundRole = match.user_metadata?.role; | |
break; | |
} | |
if (!data || users.length < perPage) break; // no more pages | |
page += 1; | |
// safety cap to avoid excessive loops | |
if (page > 50) break; | |
} | |
if (foundRole !== "admin") { | |
// Do not reveal whether the email exists; return a generic message | |
return { | |
ok: false, | |
message: "Akun tidak diizinkan melakukan reset di aplikasi admin.", | |
}; | |
} | |
} catch { | |
// Fail closed: if role check fails, do not proceed | |
return { | |
ok: false, | |
message: "Gagal memverifikasi akun. Coba lagi.", | |
}; | |
} | |
// Determine redirect URL for the password reset flow | |
const siteUrl = | |
process.env.NEXT_PUBLIC_SITE_URL?.replace(/\/$/, "") || | |
(process.env.VERCEL_URL | |
? `https://${process.env.VERCEL_URL}` | |
: "http://localhost:3000"); | |
const redirectTo = `${siteUrl}/reset-password`; | |
const { error } = await supabase.auth.resetPasswordForEmail(email, { | |
redirectTo, | |
}); | |
if (error) { | |
return { ok: false, message: "Gagal mengirim email reset. Coba lagi." }; | |
} | |
return { | |
ok: true, | |
message: "Email reset telah dikirim. Periksa kotak masuk Anda.", | |
}; | |
} | |