@snf/qa-bot-core 0.2.30-rc.1 → 0.2.30-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ interface TurnstileWidgetProps {
3
+ siteKey: string;
4
+ onVerify: (token: string) => void;
5
+ onError?: () => void;
6
+ }
7
+ /**
8
+ * Renders a Cloudflare Turnstile widget inline in the chat.
9
+ * Used as a `component` on a flow step (same pattern as LoginButton).
10
+ */
11
+ declare const TurnstileWidget: React.FC<TurnstileWidgetProps>;
12
+ export default TurnstileWidget;
@@ -2,7 +2,7 @@ import type { Settings, Flow } from 'react-chatbotify';
2
2
  /**
3
3
  * Analytics event types fired by qa-bot-core
4
4
  */
5
- export type QABotAnalyticsEventType = 'chatbot_open' | 'chatbot_close' | 'chatbot_new_chat' | 'chatbot_question_sent' | 'chatbot_answer_received' | 'chatbot_answer_error' | 'chatbot_rating_sent' | 'chatbot_login_prompt_shown' | 'chatbot_login_clicked' | 'chatbot_link_clicked';
5
+ export type QABotAnalyticsEventType = 'chatbot_open' | 'chatbot_close' | 'chatbot_new_chat' | 'chatbot_question_sent' | 'chatbot_answer_received' | 'chatbot_answer_error' | 'chatbot_rating_sent' | 'chatbot_login_prompt_shown' | 'chatbot_login_clicked' | 'chatbot_link_clicked' | 'chatbot_turnstile_shown' | 'chatbot_turnstile_completed' | 'chatbot_turnstile_error';
6
6
  /**
7
7
  * Analytics event payload
8
8
  *
@@ -83,6 +83,16 @@ export interface QABotProps {
83
83
  * - Optional: if not provided, requests will be anonymous
84
84
  */
85
85
  actingUser?: string;
86
+ /**
87
+ * Cloudflare Turnstile site key for bot protection.
88
+ * When provided, an invisible Turnstile widget is rendered on mount
89
+ * to silently verify the user. The token is attached to every query
90
+ * automatically. If silent verification fails, the backend's
91
+ * visible-challenge flow kicks in as a fallback.
92
+ *
93
+ * Omit or pass empty string to disable Turnstile entirely on the frontend.
94
+ */
95
+ turnstileSiteKey?: string;
86
96
  /**
87
97
  * Custom flow steps to merge with the built-in Q&A flow.
88
98
  * Use this to add ticket creation flows, feedback flows, etc.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * useTurnstile — silent background Turnstile verification.
3
+ *
4
+ * Renders an invisible Cloudflare Turnstile widget on mount. Most legitimate
5
+ * users get a token automatically (no UI). The token is exposed so the
6
+ * qa-flow can attach it to every request.
7
+ *
8
+ * If silent verification fails (Cloudflare deems the visitor suspicious),
9
+ * `status` becomes 'failed' and the qa-flow falls back to the existing
10
+ * visible-challenge path (backend returns requires_turnstile, widget shown
11
+ * in chat).
12
+ *
13
+ * Turnstile tokens expire after ~300 s. The widget's built-in
14
+ * `refresh-expired: auto` handles re-issuing before expiry.
15
+ */
16
+ export type TurnstileStatus = 'idle' | 'loading' | 'verified' | 'failed';
17
+ export interface UseTurnstileResult {
18
+ /** Current Turnstile token, or null if not yet verified / failed. */
19
+ token: string | null;
20
+ /** Lifecycle status of the silent verification. */
21
+ status: TurnstileStatus;
22
+ }
23
+ /**
24
+ * @param siteKey Cloudflare Turnstile site key. Pass `undefined` or empty
25
+ * string to disable (hook becomes a no-op).
26
+ */
27
+ export declare function useTurnstile(siteKey: string | undefined): UseTurnstileResult;
@@ -26,6 +26,7 @@ interface QABotConfig {
26
26
  embedded?: boolean;
27
27
  isLoggedIn: boolean;
28
28
  allowAnonAccess?: boolean;
29
+ turnstileSiteKey?: string;
29
30
  welcomeMessage: string;
30
31
  primaryColor?: string;
31
32
  secondaryColor?: string;
@@ -28,12 +28,19 @@ export interface CreateQAFlowParams {
28
28
  actingUser?: string;
29
29
  /** Enriched analytics tracker (adds common fields automatically) */
30
30
  trackEvent?: (event: AnalyticsEventInput) => void;
31
+ /**
32
+ * Returns the current silent Turnstile token (from useTurnstile hook).
33
+ * When available, attached to every request so the backend can verify
34
+ * without prompting. When null, the backend's free-query allowance
35
+ * applies, and the visible challenge is the fallback.
36
+ */
37
+ getTurnstileToken?: () => string | null;
31
38
  }
32
39
  /**
33
40
  * Creates the basic Q&A conversation flow
34
41
  * Handles questions, responses, and optional ratings
35
42
  */
36
- export declare const createQAFlow: ({ endpoint, ratingEndpoint, apiKey, sessionId: getSessionId, isResetting, isLoggedIn, allowAnonAccess, loginUrl, actingUser, trackEvent }: CreateQAFlowParams) => {
43
+ export declare const createQAFlow: ({ endpoint, ratingEndpoint, apiKey, sessionId: getSessionId, isResetting, isLoggedIn, allowAnonAccess, loginUrl, actingUser, trackEvent, getTurnstileToken, }: CreateQAFlowParams) => {
37
44
  qa_loop: {
38
45
  message: string;
39
46
  component: React.JSX.Element;
@@ -44,11 +51,11 @@ export declare const createQAFlow: ({ endpoint, ratingEndpoint, apiKey, sessionI
44
51
  };
45
52
  } | {
46
53
  qa_loop: {
47
- message: (chatState: any) => Promise<"Thanks for the feedback! Feel free to ask another question." | "I wasn't able to verify you're human. Please try your question again." | "I apologize, but I'm having trouble processing your question. Please try again later.">;
54
+ message: (chatState: any) => Promise<"Thanks for the feedback! Feel free to ask another question." | "Verification failed. Please try your question again." | "I had trouble processing your question after verification. Please try again." | "Please verify you're human to continue." | "I apologize, but I'm having trouble processing your question. Please try again later.">;
48
55
  options: (chatState: any) => string[];
49
56
  renderMarkdown: string[];
50
57
  chatDisabled: boolean;
58
+ component: React.JSX.Element;
51
59
  path: string;
52
- component?: undefined;
53
60
  };
54
61
  };
@@ -7,12 +7,13 @@
7
7
  * Usage for consumers:
8
8
  * localStorage.setItem('QA_BOT_DEBUG', 'true'); // Enable debug logs + version
9
9
  */
10
- export declare const LIB_VERSION = "0.2.19";
10
+ export declare const LIB_VERSION = "0.2.30-rc.11";
11
11
  export declare const logger: {
12
12
  version: () => void;
13
13
  session: (action: string, ...args: unknown[]) => void;
14
14
  history: (action: string, ...args: unknown[]) => void;
15
15
  message: (action: string, data: Record<string, unknown>) => void;
16
+ turnstile: (action: string, ...args: unknown[]) => void;
16
17
  warn: (...args: unknown[]) => void;
17
18
  error: (...args: unknown[]) => void;
18
19
  };
@@ -11,14 +11,14 @@
11
11
  */
12
12
  export declare function loadTurnstileScript(): Promise<void>;
13
13
  /**
14
- * Render the Turnstile widget into a container and return the token.
14
+ * Render the Turnstile widget by appending it to the last bot message bubble.
15
15
  *
16
- * Waits for the container element to appear in the DOM (since injectMessage
17
- * may not have flushed yet), then calls turnstile.render() and resolves
18
- * when the user completes the challenge.
16
+ * react-chatbotify's injectMessage() escapes HTML, so we can't inject a
17
+ * container div via message content. Instead, we wait for the text message
18
+ * to render, find the last bot message bubble in the DOM, and append the
19
+ * Turnstile widget container directly.
19
20
  *
20
21
  * @param siteKey - Cloudflare Turnstile site key (from the agent response)
21
- * @param containerId - DOM id of the container to render into
22
22
  * @returns The verification token string
23
23
  */
24
- export declare function renderTurnstileWidget(siteKey: string, containerId?: string): Promise<string>;
24
+ export declare function renderTurnstileWidget(siteKey: string): Promise<string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snf/qa-bot-core",
3
- "version": "0.2.30-rc.1",
3
+ "version": "0.2.30-rc.11",
4
4
  "description": "A configurable chatbot setup for quick integration of RAG-powered Q&A and rating system",
5
5
  "main": "./dist/qa-bot-core.umd.cjs",
6
6
  "module": "./dist/qa-bot-core.js",