AWS SES preview

This commit is contained in:
pulipakaa24
2026-03-19 19:59:01 -05:00
parent 0193240048
commit 0b4b1a6ff5
16 changed files with 2298 additions and 65 deletions

View File

@@ -2,11 +2,13 @@ import { betterAuth } from 'better-auth';
import { kyselyAdapter } from '@better-auth/kysely-adapter';
import { Kysely, PostgresDialect } from 'kysely';
import { Pool } from 'pg';
import { sendEmail, verificationEmailHtml, resetPasswordEmailHtml } from './email';
const db = new Kysely({
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL ||
connectionString:
process.env.DATABASE_URL ||
'postgresql://labwise:labwise_dev_pw@localhost:5432/labwise_db',
}),
}),
@@ -16,7 +18,35 @@ export const auth = betterAuth({
database: kyselyAdapter(db, { type: 'postgres' }),
baseURL: process.env.BETTER_AUTH_URL || 'http://localhost:3001',
secret: process.env.BETTER_AUTH_SECRET || 'dev-secret-change-in-production-min32chars!!',
secret:
process.env.BETTER_AUTH_SECRET ||
'dev-secret-change-in-production-min32chars!!',
rateLimit: {
enabled: false, // TODO: re-enable in production
},
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
sendResetPassword: async ({ user, url }) => {
await sendEmail({
to: user.email,
subject: 'Reset your LabWise password',
html: resetPasswordEmailHtml(url),
});
},
},
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
await sendEmail({
to: user.email,
subject: 'Verify your LabWise email',
html: verificationEmailHtml(url),
});
},
},
socialProviders: {
google: {

47
server/src/auth/email.ts Normal file
View File

@@ -0,0 +1,47 @@
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
const ses = new SESClient({ region: process.env.AWS_REGION || 'us-east-1' });
const FROM = process.env.FROM_EMAIL || 'noreply@labwise.wahwa.com';
export async function sendEmail({
to,
subject,
html,
}: {
to: string;
subject: string;
html: string;
}) {
await ses.send(
new SendEmailCommand({
Source: FROM,
Destination: { ToAddresses: [to] },
Message: {
Subject: { Data: subject },
Body: { Html: { Data: html } },
},
})
);
}
export function verificationEmailHtml(url: string) {
return `
<div style="font-family:sans-serif;max-width:480px;margin:0 auto;padding:32px">
<h2 style="color:#2d5a4a;margin-bottom:8px">Verify your email</h2>
<p style="color:#555;margin-bottom:24px">Click the button below to verify your email address and activate your LabWise account.</p>
<a href="${url}" style="display:inline-block;background:#5a9584;color:white;padding:12px 28px;border-radius:6px;text-decoration:none;font-weight:600">Verify Email</a>
<p style="color:#aaa;font-size:12px;margin-top:32px">If you didn't create a LabWise account, you can ignore this email.</p>
</div>
`;
}
export function resetPasswordEmailHtml(url: string) {
return `
<div style="font-family:sans-serif;max-width:480px;margin:0 auto;padding:32px">
<h2 style="color:#2d5a4a;margin-bottom:8px">Reset your password</h2>
<p style="color:#555;margin-bottom:24px">Click the button below to reset your LabWise password. This link expires in 1 hour.</p>
<a href="${url}" style="display:inline-block;background:#5a9584;color:white;padding:12px 28px;border-radius:6px;text-decoration:none;font-weight:600">Reset Password</a>
<p style="color:#aaa;font-size:12px;margin-top:32px">If you didn't request this, you can ignore this email.</p>
</div>
`;
}