|
1 | 1 |
|
2 | 2 |
|
3 | | -# Security and Bug Fix Plan |
4 | | - |
5 | | -## Summary |
6 | | -There are **2 critical bugs** and **several security findings** to address. Here's the full breakdown: |
7 | | - |
8 | | ---- |
9 | | - |
10 | | -## 1. Fix `getClaims` Bug in Lab Tools Edge Function (Critical) |
11 | | - |
12 | | -The `lab-tools` edge function has the exact same `supabase.auth.getClaims()` bug that was just fixed in `beauty-assistant`. This causes a 500 error whenever anyone uses the Lab Tools feature. |
13 | | - |
14 | | -**Fix:** Replace `getClaims(token)` with `supabase.auth.getUser()` on lines 204-210 of `supabase/functions/lab-tools/index.ts`, identical to the beauty-assistant fix. |
15 | | - |
16 | | ---- |
17 | | - |
18 | | -## 2. Fix Overly Permissive Chat Logs UPDATE Policy (Error) |
19 | | - |
20 | | -The `chat_logs` table has an UPDATE policy named "Enable read access for all users" with `USING (true)`, meaning **any authenticated user can modify any other user's chat history**. This is a serious data integrity issue. |
21 | | - |
22 | | -**Fix:** Replace the permissive policy with one restricted to the row owner: |
23 | | -```text |
24 | | -DROP the "Enable read access for all users" UPDATE policy |
25 | | -CREATE a new UPDATE policy: USING (user_id = auth.uid()) WITH CHECK (user_id = auth.uid()) |
26 | | -``` |
27 | | - |
28 | | ---- |
29 | | - |
30 | | -## 3. Update Stale Security Findings |
31 | | - |
32 | | -Several findings from the `agent_security` scanner are outdated (e.g., profiles table supposedly having no policies, when it actually does). The scan will be re-run to refresh these. |
33 | | - |
34 | | ---- |
35 | | - |
36 | | -## 4. Remaining Informational Items (No Action Needed Now) |
37 | | - |
38 | | -- **Shopify Storefront token in client code** -- already marked as ignored (Storefront tokens are designed for client-side use) |
39 | | -- **`cleanup_allowlist` table with no RLS** -- admin-only utility table, low risk |
40 | | -- **Function search_path mutable** -- cosmetic warning on some DB functions |
41 | | - |
42 | | ---- |
43 | | - |
44 | | -## Technical Steps |
45 | | - |
46 | | -1. Edit `supabase/functions/lab-tools/index.ts`: replace lines 204-210 (`getClaims` block) with `supabase.auth.getUser()` pattern |
47 | | -2. Deploy the updated `lab-tools` edge function |
48 | | -3. Apply a database migration to fix the `chat_logs` UPDATE policy |
49 | | -4. Re-run the security scan and update/dismiss resolved findings |
50 | | -5. Test the lab-tools endpoint to confirm it returns 401 (not 500) for auth validation |
| 3 | +## Plan: Enhance Intent-Based Deep Linking |
| 4 | + |
| 5 | +### Current State |
| 6 | +The `AIConcierge.tsx` already has basic deep linking (lines 169-186): it reads `?intent=` and `?source=` from the URL, opens the panel, and pre-fills the input text. However, it has several gaps: |
| 7 | + |
| 8 | +1. **No auto-send** — it only fills the input; the user must manually press Send |
| 9 | +2. **No intent-to-prompt mapping** — raw intent like "acne" becomes generic "I need help with acne" instead of a tailored clinical prompt |
| 10 | +3. **No URL cleanup** — query params remain in the URL bar after handling |
| 11 | +4. **No source tracking** — the `source` param (ig, tiktok, fb) isn't logged or used for analytics |
| 12 | + |
| 13 | +### Implementation Steps |
| 14 | + |
| 15 | +**1. Add an intent-to-prompt mapping object** in `AIConcierge.tsx` that maps common marketing intents to rich, persona-appropriate opening messages: |
| 16 | +- `acne` → "I'm struggling with acne and oiliness. What's the best clinical routine?" |
| 17 | +- `glow` → "I want radiant, glowing skin. What do you recommend?" |
| 18 | +- `anti-aging` → "I'm looking for an anti-aging routine with proven actives." |
| 19 | +- `hydration` → "My skin is very dry. I need a deep hydration regimen." |
| 20 | +- `bridal` → "I'm getting married soon! Help me with a bridal skincare bootcamp." |
| 21 | +- `pregnancy` → "I'm pregnant and need a safe skincare routine." |
| 22 | +- Fallback: `"I need help with {intent}."` |
| 23 | + |
| 24 | +**2. Modify the deep link `useEffect`** to: |
| 25 | +- Map the intent to a tailored prompt using the mapping |
| 26 | +- Auto-send the message after auth check completes (watch `isAuthenticated` state) instead of just filling the input |
| 27 | +- Clean up the URL using `window.history.replaceState` to remove `?intent=` and `?source=` params |
| 28 | +- Store `source` in a ref so it can optionally be included in the API payload for analytics |
| 29 | + |
| 30 | +**3. Add a `deepLinkIntent` ref** that stores the pending intent text, and trigger `send()` automatically once `isAuthenticated === true` — this solves the timing issue where auth hasn't resolved yet when the deep link fires. |
| 31 | + |
| 32 | +### Files Changed |
| 33 | +- `src/components/AIConcierge.tsx` — All changes in this single file |
| 34 | + |
| 35 | +### Technical Notes |
| 36 | +- Uses `window.history.replaceState` for clean URL (no page reload) |
| 37 | +- The auto-send fires only once via the existing `deepLinkHandled` ref |
| 38 | +- Intent mapping is extensible — new campaigns just add a key to the map |
51 | 39 |
|
0 commit comments