fix: address code review issues for email verification

- Use $env/dynamic/private instead of process.env (SvelteKit convention)
- Fail fast if USESEND_API_KEY is missing
- Await sendEmail with try/catch + console.error (was silently discarded)
- Fallback for user.name in email greeting
- Fix open redirect on login redirect param
This commit is contained in:
Sanju Sivalingam
2026-02-18 22:47:12 +05:30
parent 7b5685cc25
commit 9b2ca21d28
3 changed files with 15 additions and 7 deletions

View File

@@ -23,7 +23,8 @@ export const login = form(loginSchema, async (user) => {
throw err;
}
const next = url.searchParams.get('redirect') || '/dashboard';
redirect(303, next);
const safeNext = next.startsWith('/') && !next.startsWith('//') ? next : '/dashboard';
redirect(303, safeNext);
});
export const signout = form(async () => {

View File

@@ -15,11 +15,15 @@ export const auth = betterAuth({
plugins: [sveltekitCookies(getRequestEvent), apiKey()],
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
void sendEmail({
to: user.email,
subject: 'Verify your DroidClaw email',
text: `Hi ${user.name},\n\nClick the link below to verify your email:\n\n${url}\n\nThis link expires in 1 hour.\n\n-- DroidClaw`
});
try {
await sendEmail({
to: user.email,
subject: 'Verify your DroidClaw email',
text: `Hi ${user.name || 'there'},\n\nClick the link below to verify your email:\n\n${url}\n\nThis link expires in 1 hour.\n\n-- DroidClaw`
});
} catch (err) {
console.error('Failed to send verification email:', err);
}
},
sendOnSignUp: true,
sendOnSignIn: true,

View File

@@ -1,6 +1,9 @@
import { env } from '$env/dynamic/private';
import { UseSend } from 'usesend-js';
const usesend = new UseSend(process.env.USESEND_API_KEY!);
if (!env.USESEND_API_KEY) throw new Error('USESEND_API_KEY is not set');
const usesend = new UseSend(env.USESEND_API_KEY);
const EMAIL_FROM = 'noreply@app.droidclaw.ai';