@embarkai/ui-kit 0.4.127 → 0.6.9

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.
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Telegram Login - EmbarkAI</title>
6
+ <title>Telegram Login - embarkAI</title>
7
7
 
8
8
  <style>
9
9
  * {
@@ -6,6 +6,21 @@
6
6
  // Get bot username from URL parameter
7
7
  const urlParams = new URLSearchParams(window.location.search);
8
8
  const BOT_USERNAME = urlParams.get('bot');
9
+ // The dApp page that opened this popup (tss-api #6): the payload is posted to this origin only. Older SDKs pass
10
+ // none and get '*', as before (their payload gives a legacy session only).
11
+ const TARGET_ORIGIN = boundOrigin(urlParams.get('origin')) || (urlParams.get('origin') ? null : '*');
12
+
13
+ /** A bare http(s) origin, or null */
14
+ function boundOrigin(value) {
15
+ if (!value) return null;
16
+ try {
17
+ const url = new URL(value);
18
+ if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;
19
+ return url.origin === value.replace(/\/+$/, '') ? url.origin : null;
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
9
24
 
10
25
  console.log('[Telegram OAuth] Initializing with bot:', BOT_USERNAME);
11
26
 
@@ -14,13 +29,14 @@ window.onTelegramAuth = function(user) {
14
29
  console.log('[Telegram OAuth] Authentication successful:', user);
15
30
 
16
31
  try {
32
+ if (!TARGET_ORIGIN) throw new Error('Invalid origin parameter');
17
33
  // Send data to opener window
18
34
  if (window.opener) {
19
35
  window.opener.postMessage({
20
36
  type: 'TELEGRAM_AUTH_SUCCESS',
21
37
  provider: 'telegram',
22
38
  user: user
23
- }, '*');
39
+ }, TARGET_ORIGIN);
24
40
 
25
41
  // Show success message
26
42
  const container = document.getElementById('telegram-widget-container');
@@ -103,10 +119,10 @@ if (document.readyState === 'loading') {
103
119
 
104
120
  // Handle popup closing without authentication
105
121
  window.addEventListener('beforeunload', () => {
106
- if (window.opener) {
122
+ if (window.opener && TARGET_ORIGIN) {
107
123
  window.opener.postMessage({
108
124
  type: 'TELEGRAM_AUTH_CANCELLED',
109
125
  provider: 'telegram'
110
- }, '*');
126
+ }, TARGET_ORIGIN);
111
127
  }
112
128
  });
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>X (Twitter) Login - EmbarkAI</title>
6
+ <title>X (Twitter) Login - embarkAI</title>
7
7
 
8
8
  <style>
9
9
  * {
@@ -16,6 +16,25 @@ const STATE = urlParams.get('state');
16
16
  const CODE = urlParams.get('code');
17
17
  const ERROR_PARAM = urlParams.get('error');
18
18
  const SUCCESS = urlParams.get('success'); // Backend redirected with success=true
19
+ // Iframe flow (tss-api #6): the page opened this popup with ?pending=1 and navigates it to X itself;
20
+ // after the callback (flow=iframe) the code goes to the page, which hands it to the auth iframe
21
+ const PENDING = urlParams.get('pending') === '1';
22
+ const IFRAME_FLOW = urlParams.get('flow') === 'iframe';
23
+ // Iframe flow: the dApp page origin TSS bound to the flow (an allowed domain of the project); the result is
24
+ // posted to this origin only, never to '*'
25
+ const BOUND_ORIGIN = boundOrigin(urlParams.get('origin'));
26
+
27
+ /** A bare http(s) origin, or null */
28
+ function boundOrigin(value) {
29
+ if (!value) return null;
30
+ try {
31
+ const url = new URL(value);
32
+ if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;
33
+ return url.origin === value.replace(/\/+$/, '') ? url.origin : null;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
19
38
 
20
39
  console.log('[X OAuth] Initializing with:', { TSS_URL, MODE, PROJECT_ID, STATE, CODE, ERROR_PARAM, SUCCESS });
21
40
 
@@ -156,7 +175,44 @@ async function startOAuthFlow() {
156
175
  * If authCode is present, exchanges it for tokens (Safari ITP fix)
157
176
  * Otherwise falls back to cookie-based verify (desktop browsers)
158
177
  */
178
+ /**
179
+ * Iframe flow: the code is redeemable only with the auth iframe's flow secret, so it is not exchanged here.
180
+ * Linking started by the iframe session issues no code at all.
181
+ */
182
+ function handleIframeFlowSuccess() {
183
+ const authCode = urlParams.get('authCode');
184
+ if (!window.opener) {
185
+ showError('No opener window found. Please close this window manually.', false);
186
+ return;
187
+ }
188
+ if (!BOUND_ORIGIN) {
189
+ // never hand an iframe flow result to an unknown page
190
+ showError('The sign-in page is unknown. Please close this window and try again.', false);
191
+ return;
192
+ }
193
+ window.opener.postMessage({
194
+ type: 'X_AUTH_SUCCESS',
195
+ provider: 'x',
196
+ mode: MODE,
197
+ flow: 'iframe',
198
+ ...(authCode ? { authCode } : {})
199
+ }, BOUND_ORIGIN);
200
+ authResultSent = true;
201
+ showSuccess(MODE === 'link' ? 'Account linked successfully!' : 'Authentication successful!');
202
+ localStorage.removeItem('x_oauth_state');
203
+ localStorage.removeItem('x_oauth_mode');
204
+ localStorage.removeItem('x_oauth_tssUrl');
205
+ localStorage.removeItem('x_oauth_projectId');
206
+ setTimeout(() => {
207
+ window.close();
208
+ }, 1500);
209
+ }
210
+
159
211
  async function handleBackendSuccess() {
212
+ if (IFRAME_FLOW) {
213
+ handleIframeFlowSuccess();
214
+ return;
215
+ }
160
216
  try {
161
217
  showLoading('Completing authentication...');
162
218
 
@@ -387,6 +443,10 @@ if (ERROR_PARAM) {
387
443
  }, '*');
388
444
  authResultSent = true; // Mark that we've sent result
389
445
  }
446
+ } else if (PENDING) {
447
+ // The page navigates this window to X once the auth iframe has started the flow
448
+ showLoading('Starting X OAuth flow...');
449
+ isRedirectingToProvider = true;
390
450
  } else if (SUCCESS === 'true') {
391
451
  // Backend redirected back after successful OAuth
392
452
  handleBackendSuccess();