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
@@ -0,0 +1,66 @@
|
||||
// OPTIONAL pre-provisioning: creates the products + prices with stable lookup
|
||||
// keys. You don't strictly need to run this — the app auto-creates any missing
|
||||
// price on first checkout (see lib/stripe/prices.ts) — but running it once in
|
||||
// live mode pre-creates the catalog so the first real checkout is instant.
|
||||
//
|
||||
// 1. Set STRIPE_SECRET_KEY in .env.local (sk_test_... to start, sk_live_... for prod)
|
||||
// 2. node scripts/stripe-setup.mjs
|
||||
//
|
||||
// There are NO price-ID env vars to copy — prices are resolved by lookup key,
|
||||
// so going live is just an API-key swap. Amounts mirror lib/stripe/plans.ts
|
||||
// (Pro $29/mo, Landlord $59/mo, Lifetime $199 one-time; yearly = 10× monthly).
|
||||
import { config } from "dotenv"
|
||||
import Stripe from "stripe"
|
||||
|
||||
config({ path: ".env.local", quiet: true })
|
||||
|
||||
const key = process.env.STRIPE_SECRET_KEY
|
||||
if (!key) {
|
||||
console.error("[stripe-setup] Set STRIPE_SECRET_KEY in .env.local first.")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const stripe = new Stripe(key)
|
||||
const live = key.startsWith("sk_live")
|
||||
console.log(`[stripe-setup] mode: ${live ? "LIVE" : "test"}`)
|
||||
|
||||
const AMOUNTS = { pro: 29, landlord: 59, lifetime: 199 }
|
||||
const envLines = []
|
||||
|
||||
async function makeProduct(name) {
|
||||
const p = await stripe.products.create({ name: `Property Management Network — ${name}` })
|
||||
return p.id
|
||||
}
|
||||
async function makePrice(product, dollars, interval /* "month" | "year" | null */, lookupKey) {
|
||||
const p = await stripe.prices.create({
|
||||
product,
|
||||
currency: "usd",
|
||||
unit_amount: Math.round(dollars * 100),
|
||||
lookup_key: lookupKey,
|
||||
transfer_lookup_key: true,
|
||||
...(interval ? { recurring: { interval } } : {}),
|
||||
})
|
||||
return p.id
|
||||
}
|
||||
|
||||
// Pro (monthly + yearly)
|
||||
const proProduct = await makeProduct("Pro")
|
||||
envLines.push(`pmn_pro_monthly → ${await makePrice(proProduct, AMOUNTS.pro, "month", "pmn_pro_monthly")}`)
|
||||
envLines.push(`pmn_pro_yearly → ${await makePrice(proProduct, AMOUNTS.pro * 10, "year", "pmn_pro_yearly")}`)
|
||||
console.log(` Pro product: ${proProduct}`)
|
||||
|
||||
// Landlord (monthly + yearly)
|
||||
const landlordProduct = await makeProduct("Landlord")
|
||||
envLines.push(`pmn_landlord_monthly → ${await makePrice(landlordProduct, AMOUNTS.landlord, "month", "pmn_landlord_monthly")}`)
|
||||
envLines.push(`pmn_landlord_yearly → ${await makePrice(landlordProduct, AMOUNTS.landlord * 10, "year", "pmn_landlord_yearly")}`)
|
||||
console.log(` Landlord product: ${landlordProduct}`)
|
||||
|
||||
// Lifetime (one-time)
|
||||
const lifetimeProduct = await makeProduct("Lifetime")
|
||||
envLines.push(`pmn_lifetime → ${await makePrice(lifetimeProduct, AMOUNTS.lifetime, null, "pmn_lifetime")}`)
|
||||
console.log(` Lifetime product: ${lifetimeProduct}`)
|
||||
|
||||
console.log("\n[stripe-setup] Created prices with lookup keys (below). NO env vars")
|
||||
console.log("needed — the app resolves prices by lookup key, so going live is just")
|
||||
console.log("a key swap. Running this in live mode pre-creates the same keys there.\n")
|
||||
console.log(envLines.join("\n"))
|
||||
Reference in New Issue
Block a user