Feat/copilot money fix#135
Conversation
Adds api-js.mixpanel.com, *.analytics.google.com, stats.g.doubleclick.net and www.google.com to connect-src (+ www.google.com to img-src) so GA4 regional collection, the Mixpanel JS shard, and the Google Ads conversion beacon are not CSP-blocked on staging. Mirrors fixes already live on main; prevents a future dev->main merge from reverting prod's analytics fixes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The per-navigation "you're on X" landing line fires a paid Claude call on every page hop, even when the pill is closed and the visitor never interacts — so cost scaled with raw visitor count. Now the organic greeting only spends when the panel is open AND the visitor has already engaged (asked a question / clicked a card / picked a suggestion) this session. Curated landings stay local/free; card-click landings already imply both signals and are unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…cache Tighten the organic greeting cost gate per product decision: - Engagement is now set ONLY on a manually typed message. Card and suggestion clicks no longer count — clicking existing buttons is navigation, not a conversation, and must not incur paid greetings. - Engagement expires after 30 min of no typed input (timestamp + TTL), so a long-idle tab starts neutral again. - Never pay twice for the same page in a session: the organic greeting is cached per canonical path; revisits and back/forth are free. Curated (local) landings and the chat answer path are unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…+ bot filter Remember the widget's open/closed panel in sessionStorage so it follows the visitor across page loads (incl. hard reloads into UX Core), instead of always booting closed. Switch the paid organic-greeting gate from "typed within 30 min" to simply "panel open" — opening the pill is a deliberate human gesture — and add a known-bot user-agent backstop on /api/concierge-landing so we never pay a crawler that reaches the route. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude review this PR. Also, check for security issues. |
|
Claude finished @MaryWylde's task in 1m 54s —— View job PR Review: Feat/copilot money fixTasks
SummaryThis PR makes three changes across 4 commits:
Overall the direction is correct — the previous gate (requiring typed input) was too strict and broke the organic greeting for returning users. The new approach is reasonable. However there are some concerns detailed below. Security Issues🔴 Critical — No rate limiting on the paid LLM endpoint
for i in $(seq 1 1000); do
curl -s -X POST https://keepsimple.io/api/concierge-landing \
-H "Content-Type: application/json" \
-H "User-Agent: Mozilla/5.0" \
-d '{"url":"https://keepsimple.io/uxcore/'$i'","title":"test","lang":"en","mode":"organic"}'
doneRecommendation: Add server-side rate limiting by IP — e.g. 🟡 Medium — Bot UA filter is a cost-reduction hint, not a security control
Also: 🟡 Medium — No input length validation before LLM calls
const { url, title, prevQuery, prevAnswer, lang, mode } = (req.body ?? {}) as { ... };
🟢 Low — CSP
|
Address tech-lead review on /api/concierge-landing: - per-IP sliding-window rate limit (30/hr) as the real budget guard; the bot-UA filter is bypassable and only a cost hint now (comment fixed) - clamp title/prevQuery/prevAnswer before prompt injection to cap tokens Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Description
Briefly describe the changes.
🔗 Related Issue
Closes #123 or relates to #456
*(Optional: You can also open a pull request directly from an issue — GitHub will auto-link it.)
✅ Checklist