embeddedaichatux 1.9.0 → 2.0.1

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.
Files changed (2) hide show
  1. package/EmbeddedChat.js +113 -20
  2. package/package.json +1 -1
package/EmbeddedChat.js CHANGED
@@ -9,7 +9,7 @@
9
9
  this.isPreview = this.options.isPreview || false;
10
10
  this.locale = options.locale || 'en';
11
11
  this.previewParam = this.isPreview ? "?isPreview=true" : "";
12
- this.serverUrl = this.options.serverUrl || 'https://embedgpt.chat/';
12
+ this.serverUrl = this.options.serverUrl || 'https://app.bizdriver.ai/';
13
13
  this.height = options.height || 600; // Default height
14
14
  this.width = options.width || 320; // Default width
15
15
  this.marginBottom = options.marginBottom || 0;
@@ -18,6 +18,8 @@
18
18
  this.mouseInsideChat = false;
19
19
  this.hasRefreshed = false; // Flag to prevent endless loop
20
20
  this.conversationId = null;
21
+ this.userTokenProvider = options.userTokenProvider;
22
+ this.targetOrigin = "*";
21
23
 
22
24
  // Determine transition styles
23
25
  const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
@@ -39,7 +41,7 @@
39
41
  }
40
42
 
41
43
  isSafari() {
42
- var ua = navigator.userAgent.toLowerCase();
44
+ const ua = navigator.userAgent.toLowerCase();
43
45
  return ua.indexOf('safari') != -1 && ua.indexOf('chrome') == -1;
44
46
  }
45
47
 
@@ -70,40 +72,81 @@
70
72
  }
71
73
  }
72
74
 
73
- init() {
74
- this.updateIframes();
75
- this.addEventListeners();
75
+ async init() {
76
+ await this.updateIframes();
76
77
  }
77
78
 
78
79
  async updateIframes() {
79
- const cleanedServerUrl = this.serverUrl.endsWith('/') ? this.serverUrl.slice(0, -1) : this.serverUrl;
80
+ const cleanedServerUrl = this.serverUrl.endsWith('/')
81
+ ? this.serverUrl.slice(0, -1)
82
+ : this.serverUrl;
80
83
  const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
81
- const minimizedPositionStyle = `position: fixed; right: 0; bottom: 0; width: ${this.width}px; height: ${this.minimizedHeight}; z-index: 100000; ${this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : ''}`;
84
+ const minimizedPositionStyle = `
85
+ position: fixed; right: 0; bottom: 0;
86
+ width: ${this.width}px;
87
+ height: ${this.minimizedHeight};
88
+ z-index: 100000;
89
+ ${this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : ''}
90
+ `;
91
+
92
+ const params = {
93
+ isPreview: this.isPreview,
94
+ mode: this.mode,
95
+ locale: this.locale,
96
+ conversationId: this.conversationId
97
+ };
82
98
 
83
99
  const iframeHtml = `
84
- <iframe id="embedded-chat" style="${this.positionStyle}; display: none; border:none; overflow:hidden;" frameborder="0" sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation-by-user-activation" src="${this.buildIframeUrl(baseIframeUrl, { isPreview: this.isPreview, mode: this.mode, locale: this.locale, conversationId: this.conversationId })}"></iframe>
85
- <iframe id="embedded-chat-minimized" style="${minimizedPositionStyle}; display: none; border:none; overflow:hidden;" frameborder="0" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="${this.buildIframeUrl(baseIframeUrl, { isPreview: this.isPreview, isMinimized: true, locale: this.locale, conversationId: this.conversationId })}"></iframe>
86
- `;
87
-
100
+ <iframe
101
+ id="embedded-chat"
102
+ style="${this.positionStyle}; display: none; border:none; overflow:hidden;"
103
+ frameborder="0"
104
+ sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation-by-user-activation"
105
+ src="${this.buildIframeUrl(baseIframeUrl, params)}"
106
+ ></iframe>
107
+ <iframe
108
+ id="embedded-chat-minimized"
109
+ style="${minimizedPositionStyle}; display: none; border:none; overflow:hidden;"
110
+ frameborder="0"
111
+ sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
112
+ src="${this.buildIframeUrl(baseIframeUrl, { ...params, isMinimized: true })}"
113
+ ></iframe>
114
+ `;
115
+
116
+ // inject and capture references
88
117
  this.containerDiv.innerHTML = iframeHtml;
89
- this.iframe = this.containerDiv.querySelector("#embedded-chat");
90
- this.minimizedIframe = this.containerDiv.querySelector("#embedded-chat-minimized");
118
+ this.iframe = this.containerDiv.querySelector('#embedded-chat');
119
+ this.minimizedIframe = this.containerDiv.querySelector('#embedded-chat-minimized');
91
120
 
121
+ // wait for the real <iframe> element to load
92
122
  await this.waitForIframeLoad(this.iframe);
93
123
 
124
+ // now that this.iframe & this.minimizedIframe exist, hook up events
125
+ this.addEventListeners();
126
+
127
+ // Send auth to iframes after load
128
+ await this.postAuthToIframes();
129
+
130
+ // restore your ContactForm logic
94
131
  if (this.mode === 'ContactForm') {
95
- this.iframe.style.maxWidth = "100%";
96
- this.iframe.style.display = "block";
132
+ this.iframe.style.maxWidth = '100%';
133
+ this.iframe.style.display = 'block';
97
134
  }
98
135
  }
99
136
 
100
137
  addEventListeners() {
138
+ if (!this.iframe || !this.minimizedIframe) {
139
+ console.error('EmbeddedChat: iframe or minimizedIframe is not defined when trying to add event listeners.', this.iframe, this.minimizedIframe);
140
+ return;
141
+ }
101
142
  this.iframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
102
143
  this.iframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
103
144
  this.minimizedIframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
104
145
  this.minimizedIframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
105
146
 
106
147
  window.addEventListener("message", (e) => {
148
+ // Only trust messages from our server (when targetOrigin is not "*")
149
+ if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
107
150
  this.handleMessage(e);
108
151
  });
109
152
 
@@ -128,11 +171,26 @@
128
171
  message: "resize",
129
172
  width: window.innerWidth, // Ensure correct size
130
173
  height: window.innerHeight
131
- }, "*");
174
+ }, this.targetOrigin);
132
175
  }
133
176
  }
134
177
 
135
178
  handleMessage(e) {
179
+ console.log('[EmbeddedChat] Received message:', {
180
+ origin: e.origin,
181
+ type: e.data?.type,
182
+ message: e.data?.message,
183
+ chatId: e.data?.chatId,
184
+ data: e.data
185
+ });
186
+
187
+ // Allow the iframe to request a fresh token
188
+ if (typeof e.data === "object" && e.data?.type === "requestAuth") {
189
+ console.log('[EmbeddedChat] Received requestAuth message, calling postAuthToIframes');
190
+ this.postAuthToIframes();
191
+ return;
192
+ }
193
+
136
194
  if (typeof e.data === "object" && (!e.data.chatId || e.data.chatId === this.chatId)) {
137
195
  const updates = {};
138
196
 
@@ -335,7 +393,7 @@
335
393
  this.iframe.contentWindow.postMessage({
336
394
  message: "show",
337
395
  sessionInfo: this.sessionInfo || null
338
- }, "*");
396
+ }, this.targetOrigin);
339
397
  } else {
340
398
  // Schedule a single retry with a delay
341
399
  setTimeout(() => {
@@ -343,7 +401,7 @@
343
401
  this.iframe.contentWindow.postMessage({
344
402
  message: "show",
345
403
  sessionInfo: this.sessionInfo || null
346
- }, "*");
404
+ }, this.targetOrigin);
347
405
  } else {
348
406
  console.warn("iframe contentWindow is not available.");
349
407
  }
@@ -387,7 +445,7 @@
387
445
 
388
446
  // Send session info immediately if the chat is already maximized
389
447
  if (this.iframe?.contentWindow && this.iframe.style.display !== "none") {
390
- this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo }, "*");
448
+ this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo }, this.targetOrigin);
391
449
  }
392
450
  }
393
451
 
@@ -419,7 +477,7 @@
419
477
  }
420
478
 
421
479
  for (const [key, value] of Object.entries(params)) {
422
- if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && value !== null && value !== undefined) {
480
+ if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && key !== 'userToken' && value !== null && value !== undefined) {
423
481
  urlParams.set(key, value);
424
482
  }
425
483
  }
@@ -447,6 +505,41 @@
447
505
  }, { once: true }); // Ensure the listener is triggered only once
448
506
  });
449
507
  }
508
+
509
+ async postAuthToIframes() {
510
+ console.log('[EmbeddedChat] postAuthToIframes called');
511
+ if (typeof this.userTokenProvider !== 'function') {
512
+ console.warn('[EmbeddedChat] No userTokenProvider function provided');
513
+ return;
514
+ }
515
+
516
+ try {
517
+ console.log('[EmbeddedChat] Calling userTokenProvider...');
518
+ const userToken = await this.userTokenProvider();
519
+
520
+ if (!userToken) {
521
+ console.warn('[EmbeddedChat] userTokenProvider returned null/empty token');
522
+ return;
523
+ }
524
+
525
+ console.log('[EmbeddedChat] Got user token, length:', userToken?.length || 0);
526
+
527
+ if (this.iframe?.contentWindow) {
528
+ console.log('[EmbeddedChat] Sending auth message to iframe with targetOrigin:', this.targetOrigin);
529
+ this.iframe.contentWindow.postMessage({
530
+ type: 'auth',
531
+ userToken: userToken,
532
+ chatId: this.chatId
533
+ }, this.targetOrigin);
534
+ console.log('[EmbeddedChat] Auth message sent successfully');
535
+ } else {
536
+ console.error('[EmbeddedChat] iframe.contentWindow is not available');
537
+ }
538
+ // No longer send auth to minimizedIframe
539
+ } catch (err) {
540
+ console.error('[EmbeddedChat] Failed to get user token:', err);
541
+ }
542
+ }
450
543
  }
451
544
 
452
545
  export function initEmbeddedChat(containerDiv, chatId, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "embeddedaichatux",
3
- "version": "1.9.0",
3
+ "version": "2.0.1",
4
4
  "description": "A lightweight and customizable embedded AI chat UI component that seamlessly integrates into web applications, offering minimized and expanded views, with iframe-based content rendering.",
5
5
  "main": "EmbeddedChat.js",
6
6
  "scripts": {