@lightcone-ai/daemon 0.9.63 → 0.9.64
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 +1 -1
- package/src/browser-login.js +51 -23
package/package.json
CHANGED
package/src/browser-login.js
CHANGED
|
@@ -41,11 +41,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
41
41
|
.map(e => ({ e, r: e.getBoundingClientRect() }))
|
|
42
42
|
.filter(({ r }) => r.top <= boxRect.top + 120 && r.right >= boxRect.right - 140)
|
|
43
43
|
.sort((a, b) => (b.r.right + boxRect.top - b.r.top) - (a.r.right + boxRect.top - a.r.top))[0]?.e;
|
|
44
|
-
if (corner) {
|
|
45
|
-
const target = corner.closest('button, [role="button"], a, div') || corner;
|
|
46
|
-
target.click();
|
|
47
|
-
return 'corner-qr-icon';
|
|
48
|
-
}
|
|
44
|
+
if (corner) return { via: 'corner-qr-icon', rect: corner.getBoundingClientRect().toJSON() };
|
|
49
45
|
return null;
|
|
50
46
|
`,
|
|
51
47
|
getSessionValue: (cookies) =>
|
|
@@ -228,24 +224,8 @@ export class BrowserLoginSession {
|
|
|
228
224
|
// Try to click the QR scan login tab if present (some platforms default to password login)
|
|
229
225
|
if (this._config.qrTabSelector) {
|
|
230
226
|
try {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
expression: `(function() {
|
|
234
|
-
const sels = ${JSON.stringify(selectors)};
|
|
235
|
-
for (const s of sels) {
|
|
236
|
-
const el = document.querySelector(s);
|
|
237
|
-
if (el) { el.click(); return s; }
|
|
238
|
-
}
|
|
239
|
-
// Also try text-based search
|
|
240
|
-
const all = [...document.querySelectorAll('a,button,span,div')];
|
|
241
|
-
const el = all.find(e => e.innerText?.trim() === '扫码登录' || e.innerText?.trim() === '二维码登录');
|
|
242
|
-
if (el) { el.click(); return 'text:' + el.innerText.trim(); }
|
|
243
|
-
${this._config.qrFallbackScript ?? ''}
|
|
244
|
-
return null;
|
|
245
|
-
})()`,
|
|
246
|
-
returnByValue: true,
|
|
247
|
-
});
|
|
248
|
-
console.log(`[BrowserLogin][${this._platform}] QR switch result: ${qrResult.result?.value ?? 'not-found'}`);
|
|
227
|
+
const qrResult = await this._switchToQrLogin();
|
|
228
|
+
console.log(`[BrowserLogin][${this._platform}] QR switch result: ${qrResult?.via ?? 'not-found'}`);
|
|
249
229
|
await sleep(1000);
|
|
250
230
|
} catch (err) {
|
|
251
231
|
console.error(`[BrowserLogin][${this._platform}] QR switch failed: ${err.message}`);
|
|
@@ -306,6 +286,54 @@ export class BrowserLoginSession {
|
|
|
306
286
|
return result.data;
|
|
307
287
|
}
|
|
308
288
|
|
|
289
|
+
async _switchToQrLogin() {
|
|
290
|
+
const selectors = this._config.qrTabSelector ?? [];
|
|
291
|
+
const result = await this.send('Runtime.evaluate', {
|
|
292
|
+
expression: `(function() {
|
|
293
|
+
const visible = (el) => {
|
|
294
|
+
const r = el.getBoundingClientRect();
|
|
295
|
+
const cs = getComputedStyle(el);
|
|
296
|
+
return r.width > 0 && r.height > 0 && cs.display !== 'none' && cs.visibility !== 'hidden';
|
|
297
|
+
};
|
|
298
|
+
const hit = (el, via) => {
|
|
299
|
+
if (!el) return null;
|
|
300
|
+
const target = el.closest('button, [role="button"], a') || el;
|
|
301
|
+
const rect = target.getBoundingClientRect();
|
|
302
|
+
if (rect.width <= 0 || rect.height <= 0) return null;
|
|
303
|
+
return { via, rect: rect.toJSON() };
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const sels = ${JSON.stringify(selectors)};
|
|
307
|
+
for (const s of sels) {
|
|
308
|
+
const el = document.querySelector(s);
|
|
309
|
+
if (el && visible(el)) return hit(el, s);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const textElements = [...document.querySelectorAll('a,button,span,div')].filter(visible);
|
|
313
|
+
const textEl = textElements.find(e => {
|
|
314
|
+
const t = (e.innerText || e.textContent || '').trim();
|
|
315
|
+
return t === '扫码登录' || t === '二维码登录' || t === '扫码';
|
|
316
|
+
});
|
|
317
|
+
const textHit = hit(textEl, textEl ? 'text:' + (textEl.innerText || textEl.textContent || '').trim() : '');
|
|
318
|
+
if (textHit) return textHit;
|
|
319
|
+
|
|
320
|
+
${this._config.qrFallbackScript ?? 'return null;'}
|
|
321
|
+
})()`,
|
|
322
|
+
returnByValue: true,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const hit = result.result?.value;
|
|
326
|
+
const rect = hit?.rect;
|
|
327
|
+
if (!rect) return null;
|
|
328
|
+
|
|
329
|
+
const x = Math.round(rect.left + rect.width / 2);
|
|
330
|
+
const y = Math.round(rect.top + rect.height / 2);
|
|
331
|
+
await this.send('Input.dispatchMouseEvent', { type: 'mouseMoved', x, y }, 5_000);
|
|
332
|
+
await this.send('Input.dispatchMouseEvent', { type: 'mousePressed', x, y, button: 'left', clickCount: 1 }, 5_000);
|
|
333
|
+
await this.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x, y, button: 'left', clickCount: 1 }, 5_000);
|
|
334
|
+
return { via: hit.via, x, y };
|
|
335
|
+
}
|
|
336
|
+
|
|
309
337
|
async isLoggedIn(baseline) {
|
|
310
338
|
const result = await this.send('Network.getAllCookies', {});
|
|
311
339
|
return this._config.isLoggedIn(result.cookies ?? [], baseline);
|