# Security — TradeDoc Web

## Vue d'ensemble

TradeDoc Web est une application statique (HTML/JS) avec des fonctions serverless Vercel pour Stripe. L'accès à l'application (`app.html`) est **gated par abonnement Stripe vérifié côté serveur**, pas uniquement par `localStorage`.

## Authentification & accès

- **Comptes** : stockage local (`localStorage`) — migration Supabase Auth prévue.
- **Abonnement** : source de vérité = API Stripe via `/api/verify-access`.
- **app.html** : `requireActiveSubscription()` au boot + re-vérification toutes les 5 minutes + à chaque navigation (`showView`).
- **localStorage** : manipulation locale ne suffit pas — le serveur re-vérifie l'email → subscription Stripe active.
- **Signup** : crée un compte sans accès app ; redirection vers tarifs / checkout Stripe.
- **Mode démo** : désactivé en production (`*.vercel.app`, `tradedoc.app`). Uniquement sur `localhost`.

## Stripe

- Clés secrètes (`sk_*`) **uniquement** dans les variables d'environnement Vercel — jamais côté client.
- Clé publique (`pk_*`) via `/api/stripe-config`.
- Checkout Sessions en mode `subscription` avec `metadata.planId` sur session et subscription.
- Webhook : vérification stricte de signature (`stripe.webhooks.constructEvent`) — rejet sans `STRIPE_WEBHOOK_SECRET`.
- Customer Portal : `/api/create-portal-session` pour upgrade/downgrade via Stripe.

## API serverless

| Route | Protection |
|-------|------------|
| `/api/verify-access` | Rate limit 30/min/IP |
| `/api/create-checkout-session` | Rate limit 20/min/IP |
| `/api/get-subscription` | Rate limit 30/min/IP |
| `/api/create-portal-session` | Rate limit 20/min/IP |
| `/api/webhook` | Signature Stripe obligatoire |

Rate limiting : couche basique en mémoire (par instance serverless). Compléter avec Vercel Firewall / WAF en production si besoin.

## Headers HTTP (`vercel.json`)

- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `Referrer-Policy: strict-origin-when-cross-origin`
- `Permissions-Policy` restrictive
- `Content-Security-Policy` basique (self + Stripe + Google Fonts)

## Plans & feature gating

Limites définies dans `js/plans.js` (client) et `api/_plans.js` (serveur) :

| Plan | Dossiers/mois | Docs | Branding | Multi-export |
|------|---------------|------|----------|--------------|
| Starter 49€ | 20 | 4 types | Non | Non |
| Pro 99€ | Illimité | Tous sauf contrat | Oui | Oui |
| Business 199€ | Illimité | Tous | Oui | Oui |

Génération de documents bloquée côté client si plan insuffisant (toast + redirect `billing.html`).

## Données utilisateur

- Données métier (clients, produits, dossiers) en `localStorage` navigateur.
- Export JSON disponible depuis `billing.html`.
- Pas de persistance serveur des documents (hors Stripe customer/subscription).

## Signalement

Pour signaler une vulnérabilité : contact@obifruit.fr (ou l'email support de votre déploiement).

## Checklist déploiement

- [ ] Variables Vercel Production : `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, price IDs, `STRIPE_WEBHOOK_SECRET`
- [ ] Webhook Stripe pointé vers `https://<domaine>/api/webhook`
- [ ] Customer Portal activé dans Stripe Dashboard
- [ ] `npm run test:stripe` passe sur l'URL de prod
- [ ] Vérifier `/api/verify-access?email=<payant>` → `authorized: true`
