kyd-shared-badge 0.3.7 → 0.3.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kyd-shared-badge",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "private": false,
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -53,6 +53,19 @@ export default function ChatWidget({ api = '/api/chat', title = 'KYD Bot', hintT
53
53
  if (listRef.current) listRef.current.scrollTop = listRef.current.scrollHeight;
54
54
  }, [messages, open]);
55
55
 
56
+ // Prefill input from URL chatPrompt and open the sidebar when present
57
+ useEffect(() => {
58
+ try {
59
+ if (typeof window === 'undefined') return;
60
+ const url = new URL(window.location.href);
61
+ const prompt = url.searchParams.get('chatPrompt');
62
+ if (prompt && prompt.trim()) {
63
+ setInput(prompt);
64
+ setOpen(true);
65
+ }
66
+ } catch {}
67
+ }, [setInput]);
68
+
56
69
  // Optional hint (only shows if user hasn't dismissed before and when collapsed)
57
70
  useEffect(() => {
58
71
  try {
@@ -13,6 +13,18 @@ export default function ChatWindowStreaming({ api = '/api/chat', badgeId }: { ap
13
13
  if (listRef.current) listRef.current.scrollTop = listRef.current.scrollHeight;
14
14
  }, [messages]);
15
15
 
16
+ // Prefill input from URL chatPrompt if present
17
+ useEffect(() => {
18
+ try {
19
+ if (typeof window === 'undefined') return;
20
+ const url = new URL(window.location.href);
21
+ const prompt = url.searchParams.get('chatPrompt');
22
+ if (prompt && prompt.trim()) {
23
+ setInput(prompt);
24
+ }
25
+ } catch {}
26
+ }, [setInput]);
27
+
16
28
  return (
17
29
  <div className="flex flex-col border rounded-lg overflow-hidden" style={{ background: 'var(--content-card-background)', borderColor: 'var(--icon-button-secondary)'}}>
18
30
  <div ref={listRef} className="p-4 space-y-3 h-72 overflow-auto">
@@ -28,6 +28,16 @@ export function useChatStreaming(cfg: UseChatStreamingConfig) {
28
28
  const assistantId = crypto.randomUUID();
29
29
  setMessages(m => [...m, userMsg, { id: assistantId, role: 'assistant', content: '' }]);
30
30
 
31
+ const redirectToLogin = (promptText: string) => {
32
+ // Inform the user then redirect to login carrying callbackUrl and prompt
33
+ setMessages(m => m.map(msg => msg.id === assistantId ? { ...msg, content: 'You need to log in to use chat. Redirecting to login…' } : msg));
34
+ const currentPath = typeof window !== 'undefined' ? (window.location.pathname + window.location.search + window.location.hash) : '/';
35
+ const loginUrl = `/auth/login?callbackUrl=${encodeURIComponent(currentPath)}&chatPrompt=${encodeURIComponent(promptText)}`;
36
+ setTimeout(() => {
37
+ if (typeof window !== 'undefined') window.location.href = loginUrl;
38
+ }, 700);
39
+ };
40
+
31
41
  try {
32
42
  abortRef.current?.abort();
33
43
  abortRef.current = new AbortController();
@@ -35,6 +45,7 @@ export function useChatStreaming(cfg: UseChatStreamingConfig) {
35
45
  let sid = sessionId;
36
46
  if (!sid) {
37
47
  const sres = await fetch(`${api}/session`, { method: 'POST' });
48
+ if (sres.status === 401) { redirectToLogin(content); return; }
38
49
  if (!sres.ok) throw new Error('session');
39
50
  const sj = await sres.json();
40
51
  sid = sj.sessionId as string;
@@ -46,6 +57,7 @@ export function useChatStreaming(cfg: UseChatStreamingConfig) {
46
57
  body: JSON.stringify({ content, sessionId: sid, badgeId }),
47
58
  signal: abortRef.current.signal,
48
59
  });
60
+ if (res.status === 401) { redirectToLogin(content); return; }
49
61
  if (!res.ok || !res.body) throw new Error(`send: ${res.status}`);
50
62
 
51
63
  const reader = res.body.getReader();
package/src/lib/routes.ts CHANGED
@@ -5,7 +5,6 @@ import { NextRequest } from 'next/server';
5
5
  import { streamText } from 'ai';
6
6
  import { bedrock } from '@ai-sdk/amazon-bedrock';
7
7
 
8
- // import { verifyCognito } from './auth-verify';
9
8
  import { getHistory, putMessage } from './chat-store';
10
9
  import { aggregateUserData, cleanDeveloperProfile, buildAllContextPrompt, getReportGraphData } from './context';
11
10
  import { checkAndConsumeToken } from './rate-limit';
@@ -17,7 +16,6 @@ export const runtime = 'nodejs';
17
16
 
18
17
  export async function chatStreamRoute(req: NextRequest, userId: string, companyId?: string) {
19
18
  try {
20
- // const user = await verifyCognito(req);
21
19
 
22
20
  const { sessionId, content, badgeId } = await req.json();
23
21
  if (!content || !sessionId) {
@@ -70,7 +68,6 @@ export async function chatStreamRoute(req: NextRequest, userId: string, companyI
70
68
 
71
69
  export async function createSessionRoute(req: NextRequest, userId: string, companyId?: string) {
72
70
  try {
73
- // const user = await verifyCognito(req);
74
71
  const body = await req.json().catch(() => ({}));
75
72
  const sessionId = await createSession({
76
73
  userId: userId,