Bot contact defaults: owner recipients, reply-to fallback, effective values in the console - #473
Merged
Merged
Conversation
The dashboard, the AI install prompt and the developer email listed only script-src and connect-src. The widget's stylesheet loads from the script's origin, so a site with a style-src policy loaded the widget and then showed nothing: the app waits for that stylesheet before rendering. The lead capture form also rendered an inline <style> with a keyframe index.css already defines, which a style-src without 'unsafe-inline' blocks. It is removed, and csp.spec.js now runs the widget under exactly the documented policy.
New bots save the owner's email as the default notification recipient and
copy the account's company name. Every Reply-To now resolves through
get_reply_to_address (saved address, then the account owner), so replies
to team alerts and visitor emails stop landing in the no-reply inbox.
A migration saves a default recipient list on every existing bot: legacy
notification_email moves into notification_emails.default, other bots get
their owner's email, and Eventus and the eval bot get gaurav@fynix.digital.
The console names the account owner wherever an empty field falls back to
it, shows a schedule with no saved zone in UTC as the server runs it, says
Always available (24/7) when there is no schedule, and on Free explains the
real pricing behaviour and which contact page the chatbot links to (new
GET /bots/{id}/contact-link).
Every new account and operator row now starts with muted push events, and
the widget's fallback colour matches the API default.
A default recipient list that is still exactly the old owner address now follows a confirmed login email change, as the send-time fallback did. Impersonation sessions can no longer rewrite notification_emails. Alert paths resolve Reply-To only when there are recipients, the console clears the legacy notification_email it folds into the default list, and the backfill guards jsonb_array_elements with CASE.
CI builds the widget with VITE_WIDGET_BASE=https://cdn.oyechats.com/, so the app's preload hints for lazy chunks point at the CDN rather than the preview server, and a 'self'-only policy reported them as violations. The spec now uses the documented origin plus 'self' for the local preview.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Audit of 2026-09-17: all 8 production bots had no notification recipients, no reply-to and no business hours saved. Alerts still reached owners through a send-time fallback, but the console said "No recipient set... nowhere to go", and with no Reply-To header, replies to team and visitor emails went to notifications@oyechats.com and were lost.
What changes
Backend
email_service.get_reply_to_address: the saved reply-to, else the account owner's email. All 10 senders use it; an AST guard blocks direct reads.New bots (
POST /botsand paid per-bot checkout) savenotification_emails.default = [owner email]and copyClient.company_name(not locked, so the crawl can still refresh it).Migration
b1000015recipientsbackfill:notification_emailintonotification_emails.default;bot-2cd622e21f80) and Eval Bot (bot-7b18925d18a7) gaurav@fynix.digital.A read-only preview on prod shows all 8 bots get the expected address. The downgrade is a no-op. No business-hours backfill.
A confirmed login email change moves any default list that is still exactly the old owner address.
BotResponse.owner_emailis exposed, and there is a newGET /bots/{id}/contact-link(the effective contact page and where it came from).Impersonation sessions can no longer rewrite
notification_emails.Every new
ClientandOperatorrow starts withmuted_push_preferences(). Google signup, superadmin-created, affiliate, invite acceptance, owner self-add and the WS owner row skipped it; an AST guard now enforces it.Console
pricing_gate(pricing link, then contact page, then knowledge base);Widget
DEFAULT_PRIMARY_COLOR(#a21caf, the API default) instead of 35#3A0CA3literals, with a guard test.QueueWaitingScreendefaults to 60s. The component is still not mounted anywhere.Checks
An independent review found no P0. Its two P1s (owner email change, impersonation gap) and five P2s are fixed in the second commit.
Also in this PR: 7ad3dfb (CSP style-src guidance), already on development.