Etsy returns 403 'Shared secret is required in x-api-key header' when the
keystring is used on resource endpoints: the keystring is only the OAuth
client id. Store the shared secret alongside it (Settings form + env
fallback) and send it as x-api-key on users/me and receipt requests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New EtsySettings model holds the per-user API keystring and callback URL,
managed via GET/PUT /api/etsy/config; env vars remain as optional fallback
- Settings UI gains an API Configuration form (masked saved key, callback URL
prefilled with this origin's /api/etsy/callback); Connect is enabled once
configuration is saved
- OAuth and sync resolve the key per user; post-callback redirect derives
from the stored callback URL origin instead of CLIENT_URL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>