Consolidate audit-fixes branch: webhooks, integrations, and deploy hardening
Batch commit of the pending working tree on security/audit-fixes-2026-07. Major areas: - Outbound webhooks / Zapier: schema + signed delivery with retries, public v1 API (REST-hook subscribe/unsubscribe), settings UI, cron drain. - Deploy hardening: email via SMTP2GO (Resend fully removed), verified DB TLS (DATABASE_SSL=require + DATABASE_CA), storage fails loud in production when Spaces is unconfigured instead of silently using ephemeral disk. - Integrations & features (concurrent work): accounting (QuickBooks/Xero), e-signature (DocuSign/Dropbox Sign), PayPal, geocoding/maps, onboarding, expanded legal pages. - DB migrations 0006–0009. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
969d5d4c8a
commit
c9968531e4
+5
-39
@@ -4,7 +4,7 @@ import { nextCookies } from "better-auth/next-js"
|
||||
import { admin } from "better-auth/plugins"
|
||||
import { db } from "@/lib/db"
|
||||
import { user, session, account, verification, profiles } from "@/lib/db/schema"
|
||||
import { sendEmail } from "@/lib/email/send"
|
||||
import { sendEmail, resetPasswordHtml, verifyEmailHtml } from "@/lib/email/send"
|
||||
|
||||
// Bootstrap superadmins from env — no API path lets a user self-promote.
|
||||
const ADMIN_USER_IDS = (process.env.ADMIN_USER_IDS ?? "")
|
||||
@@ -22,7 +22,7 @@ export const auth = betterAuth({
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
// Env-gated so production can require a verified email without breaking
|
||||
// local dev (where RESEND is typically unconfigured). Set
|
||||
// local dev (where SMTP is typically unconfigured). Set
|
||||
// REQUIRE_EMAIL_VERIFICATION=true in production to enforce.
|
||||
requireEmailVerification: process.env.REQUIRE_EMAIL_VERIFICATION === "true",
|
||||
minPasswordLength: 8,
|
||||
@@ -38,6 +38,9 @@ export const auth = betterAuth({
|
||||
// is gated by REQUIRE_EMAIL_VERIFICATION (see emailAndPassword above).
|
||||
emailVerification: {
|
||||
sendOnSignUp: true,
|
||||
// After the user clicks the verification link, sign them in and send them
|
||||
// to the callbackURL (set to /dashboard on sign-up).
|
||||
autoSignInAfterVerification: true,
|
||||
sendVerificationEmail: async ({ user: u, url }) => {
|
||||
await sendEmail({
|
||||
to: u.email,
|
||||
@@ -88,40 +91,3 @@ export const auth = betterAuth({
|
||||
],
|
||||
})
|
||||
|
||||
function resetPasswordHtml(url: string) {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="font-family: sans-serif; background: #09090b; color: #fff; padding: 40px 20px; max-width: 560px; margin: 0 auto;">
|
||||
<div style="background: #16161f; border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 32px;">
|
||||
<h1 style="font-size: 20px; margin: 0 0 8px; color: #fff;">Reset your password</h1>
|
||||
<p style="color: rgba(255,255,255,0.6); margin: 0 0 24px;">
|
||||
Click the button below to choose a new password. If you didn't request this, you can ignore this email.
|
||||
</p>
|
||||
<a href="${url}" style="display: inline-block; background: #6366f1; color: #fff; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">
|
||||
Reset Password
|
||||
</a>
|
||||
<p style="color: rgba(255,255,255,0.4); font-size: 12px; margin: 24px 0 0;">Property Management Network</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
function verifyEmailHtml(url: string) {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="font-family: sans-serif; background: #09090b; color: #fff; padding: 40px 20px; max-width: 560px; margin: 0 auto;">
|
||||
<div style="background: #16161f; border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 32px;">
|
||||
<h1 style="font-size: 20px; margin: 0 0 8px; color: #fff;">Verify your email</h1>
|
||||
<p style="color: rgba(255,255,255,0.6); margin: 0 0 24px;">
|
||||
Confirm your email address to finish setting up your account. If you didn't create an account, you can ignore this email.
|
||||
</p>
|
||||
<a href="${url}" style="display: inline-block; background: #6366f1; color: #fff; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">
|
||||
Verify Email
|
||||
</a>
|
||||
<p style="color: rgba(255,255,255,0.4); font-size: 12px; margin: 24px 0 0;">Property Management Network</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user