Commit Graph

8 Commits

Author SHA1 Message Date
Serge RAKOTO HARRY-NAIVO
f74ff56fc4 feat(mount): extract mountWidget + applyStyles helpers with shadow support
mountWidget centralizes both classic and shadow mounting behind a single
entry point. The shadow path attaches an open shadow root, injects CSS via
constructable stylesheets (with a deduped <style>-tag fallback for jsdom
and Safari < 16.4), and renders Preact into a stable inner wrapper so the
sibling style node is not clobbered by render() diffs.

applyStyles is exported separately so the fallback branch can be exercised
directly in unit tests without a full mount round trip — the constructable
path runs only in real browsers.

Idempotency on the host element and shadow root means repeated boots
(HMR, accidental double-load) do not duplicate DOM nodes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:55:02 +02:00
Serge RAKOTO HARRY-NAIVO
8d0696584c feat(config): parse data-shadow attribute on script tag
Adds the boolean field consumed by the upcoming Shadow DOM mount path.
Strict equality with the string "true" — anything else (absent, "false",
"1", "yes", empty) yields false, so accidental opt-in is impossible.

Tests cover the full parseConfig surface (required fields, server-url
derivation, position default) plus the new shadow attribute parsing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:52:27 +02:00
Serge RAKOTO HARRY-NAIVO
ca084735ac chore(test): bootstrap vitest + jsdom test infrastructure
Add vitest 4.1, jsdom 25, and @testing-library/preact as devDeps so the
widget gets a real test surface for the upcoming Shadow DOM mount work.

- vitest.config.ts mirrors the build aliases (preact/compat) and uses
  jsdom for DOM-touching tests.
- tests/setup.ts is the place to add polyfills as the surface grows.
- tests/unit/smoke.test.ts confirms vitest runs, jsdom is wired, and
  Shadow DOM API is available.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:50:45 +02:00
c5d1880589 Merge pull request 'security(transport): subprotocol + Authorization header for webchat auth' (#2) from feat/webchat-auth-hardening into main 2026-04-27 16:36:15 +03:00
Serge RAKOTO HARRY-NAIVO
c241b3e100 security(transport): use subprotocol + Authorization header for auth
Match the bot-side hardening
(serge/messenger-bot feat/webchat-auth-hardening): credentials no longer
leak via URL query strings.

  * WebSocket handshake uses Sec-WebSocket-Protocol subprotocols
    (messenzy.v1, messenzy-bot.<id>, messenzy-visitor.<id>,
    messenzy-key.<key>) — the browser WebSocket ctor doesn't accept
    custom headers, so subprotocols are the standard pattern.

  * HTTP fallback (/webchat/msg, /webchat/history) uses
    `Authorization: Bearer <apiKey>` — fetch supports custom headers.

  * botId/visitorId stay in body/query as public identifiers; only the
    apiKey moves off the URL.

No public API change — `createTransport(opts)` takes the same
TransportOpts as before.
2026-04-27 15:25:08 +02:00
c7edf8c66c Merge pull request 'feat(widget): SP6 PR S6-1+2 - repo scaffolding + Preact bundle' (#1) from feat/sp6-s6-1-2-scaffolding-bundle into main 2026-04-26 01:11:07 +03:00
Serge RAKOTO HARRY-NAIVO
9676bbf09f feat(widget): SP6 PR S6-1+2 - messenzy-widget repo scaffolding (Preact + Vite)
- package.json with Preact 10 + Vite 6 + TypeScript 5
- vite.config: IIFE + ESM lib outputs, preact/compat alias, CSS inlined via
  ?inline import (no separate .css file emitted - single-file IIFE)
- tsconfig.json (src/) + tsconfig.node.json (vite.config.ts)
- src/index.ts: entry, injects <style>, mounts <Widget /> on script load
- src/config.ts: parses data-bot-id + data-api-key + data-server-url
- src/vite-env.d.ts: ?inline CSS type declaration
- src/storage/visitor.ts: localStorage UUID v4 with in-memory fallback
- src/transport/ws-client.ts: WebSocket primary, exponential reconnect
  (max 5 retries ~30s cap), HTTP polling fallback at /webchat/history every 5s
- src/ui/widget.tsx: root Preact component, transport lifecycle, send handler
- src/ui/bubble.tsx: floating FAB with chat/close SVG icons, position aware
- src/ui/panel.tsx: header + scrollable message list + typing indicator + input
- src/ui/message.tsx: single message bubble (user right/bot left), timestamp
- src/ui/theme.css: CSS variables (--messenzy-primary/accent overridable)
- Build output: dist/messenzy-widget.iife.js 25.3 kB (9.7 kB gz), zero errors
- typecheck: clean (strict + exactOptionalPropertyTypes)
- .gitignore: node_modules/ dist/ .vite/ .env* .DS_Store
- README: integration snippet, script attributes table, theme, build instructions
2026-04-26 00:10:12 +02:00
dd789eee49 Initial commit 2026-04-26 01:04:28 +03:00