diff --git a/public/change-email.html b/public/change-email.html new file mode 100644 index 0000000..b1578ee --- /dev/null +++ b/public/change-email.html @@ -0,0 +1,353 @@ + + + + + +Change Email — DocFast + + + + + + + + + + + +
+
+ + +
+

Change Email

+

Enter your API key and new email address.

+
+
+ + +
+
+ + +
+ +

A 6-digit code will be sent to your new email address

+
+ + +
+
+
+

Sending verification code…

+
+
+ + +
+

Check your inbox

+

We sent a 6-digit code to

+
+
+ + +
+ +

Code expires in 15 minutes

+
+ + +
+
+
+

Email updated!

+

Your account email has been changed to

+ Back to Home → +
+
+ +
+
+ + + + + + + diff --git a/public/impressum.html b/public/impressum.html index e5a0622..d762d6b 100644 --- a/public/impressum.html +++ b/public/impressum.html @@ -99,7 +99,7 @@ footer .container { display: flex; justify-content: space-between; align-items: Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service diff --git a/public/index.html b/public/index.html index 2ba719b..220a3de 100644 --- a/public/index.html +++ b/public/index.html @@ -444,7 +444,7 @@ html, body { Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service @@ -544,64 +544,7 @@ html, body { - - - - diff --git a/public/partials/_footer.html b/public/partials/_footer.html index 706cbd9..2e91056 100644 --- a/public/partials/_footer.html +++ b/public/partials/_footer.html @@ -5,7 +5,7 @@ Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service diff --git a/public/privacy.html b/public/privacy.html index 6a36e2d..664d6b9 100644 --- a/public/privacy.html +++ b/public/privacy.html @@ -181,7 +181,7 @@ footer .container { display: flex; justify-content: space-between; align-items: Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service diff --git a/public/sitemap.xml b/public/sitemap.xml index 967a532..c5ae34a 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -5,4 +5,5 @@ https://docfast.dev/impressum2026-02-16monthly0.3 https://docfast.dev/privacy2026-02-16monthly0.3 https://docfast.dev/terms2026-02-16monthly0.3 + https://docfast.dev/change-email2026-02-17monthly0.5 diff --git a/public/src/change-email.html b/public/src/change-email.html new file mode 100644 index 0000000..0e57e71 --- /dev/null +++ b/public/src/change-email.html @@ -0,0 +1,293 @@ + + + + + +Change Email — DocFast + + + + +{{> styles_base}} + + + + +{{> nav}} + +
+
+ + +
+

Change Email

+

Enter your API key and new email address.

+
+
+ + +
+
+ + +
+ +

A 6-digit code will be sent to your new email address

+
+ + +
+
+
+

Sending verification code…

+
+
+ + +
+

Check your inbox

+

We sent a 6-digit code to

+
+
+ + +
+ +

Code expires in 15 minutes

+
+ + +
+
+
+

Email updated!

+

Your account email has been changed to

+ Back to Home → +
+
+ +
+
+ +{{> footer}} + + + + + diff --git a/public/src/index.html b/public/src/index.html index 3ceaaa1..889ac89 100644 --- a/public/src/index.html +++ b/public/src/index.html @@ -219,64 +219,7 @@ - - - - diff --git a/public/status.html b/public/status.html index ed8f78f..9ba85f1 100644 --- a/public/status.html +++ b/public/status.html @@ -95,7 +95,7 @@ footer .container { display: flex; justify-content: space-between; align-items: Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service diff --git a/public/terms.html b/public/terms.html index 70953bf..fe87b95 100644 --- a/public/terms.html +++ b/public/terms.html @@ -253,7 +253,7 @@ footer .container { display: flex; justify-content: space-between; align-items: Home Docs API Status - Change Email + Change Email Impressum Privacy Policy Terms of Service diff --git a/src/routes/billing.ts b/src/routes/billing.ts index 3bf9c9d..262b298 100644 --- a/src/routes/billing.ts +++ b/src/routes/billing.ts @@ -1,6 +1,6 @@ import { Router, Request, Response } from "express"; import Stripe from "stripe"; -import { createProKey, downgradeByCustomer } from "../services/keys.js"; +import { createProKey, downgradeByCustomer, updateEmailByCustomer } from "../services/keys.js"; import logger from "../services/logger.js"; function escapeHtml(s: string): string { @@ -210,6 +210,18 @@ router.post("/webhook", async (req: Request, res: Response) => { logger.info({ customerId }, "customer.subscription.deleted: downgraded key to free tier"); break; } + case "customer.updated": { + const customer = event.data.object as Stripe.Customer; + const customerId = customer.id; + const newEmail = customer.email; + if (customerId && newEmail) { + const updated = await updateEmailByCustomer(customerId, newEmail); + if (updated) { + logger.info({ customerId, newEmail }, "Customer email synced from Stripe"); + } + } + break; + } default: break; } diff --git a/src/services/keys.ts b/src/services/keys.ts index 2218441..0ad7f3f 100644 --- a/src/services/keys.ts +++ b/src/services/keys.ts @@ -129,3 +129,11 @@ export async function updateKeyEmail(apiKey: string, newEmail: string): Promise< await pool.query("UPDATE api_keys SET email = $1 WHERE key = $2", [newEmail, apiKey]); return true; } + +export async function updateEmailByCustomer(stripeCustomerId: string, newEmail: string): Promise { + const entry = keysCache.find(k => k.stripeCustomerId === stripeCustomerId); + if (!entry) return false; + entry.email = newEmail; + await pool.query(UPDATE api_keys SET email = $1 WHERE stripe_customer_id = $2, [newEmail, stripeCustomerId]); + return true; +}