@apitap/core 1.0.8 → 1.0.10
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/auth/handoff.ts +9 -4
- package/src/capture/session.ts +16 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apitap/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Intercept web API traffic during browsing. Generate portable skill files so AI agents can call APIs directly instead of scraping.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/src/auth/handoff.ts
CHANGED
|
@@ -144,21 +144,26 @@ async function doHandoff(
|
|
|
144
144
|
// Navigate to login page
|
|
145
145
|
await page.goto(loginUrl, { waitUntil: 'domcontentloaded', timeout: 30_000 });
|
|
146
146
|
|
|
147
|
-
//
|
|
147
|
+
// Baseline: snapshot cookie names present BEFORE login so we can detect new ones
|
|
148
|
+
const baselineCookies = await context.cookies();
|
|
149
|
+
const baselineCookieNames = new Set(baselineCookies.map(c => c.name));
|
|
150
|
+
|
|
151
|
+
// Poll for login success: check for NEW session-like cookies
|
|
148
152
|
const startTime = Date.now();
|
|
149
153
|
let loginDetected = false;
|
|
150
154
|
|
|
151
155
|
while (Date.now() - startTime < timeout) {
|
|
152
156
|
await page.waitForTimeout(2000);
|
|
153
157
|
|
|
154
|
-
//
|
|
158
|
+
// Only trigger on NEW session-like cookies not present at page load
|
|
155
159
|
const cookies = await context.cookies();
|
|
156
|
-
const
|
|
160
|
+
const hasNewSessionCookie = cookies.some(c =>
|
|
161
|
+
!baselineCookieNames.has(c.name) &&
|
|
157
162
|
SESSION_COOKIE_PATTERNS.some(p => p.test(c.name)) &&
|
|
158
163
|
!TRACKING_COOKIE_PATTERNS.some(p => p.test(c.name))
|
|
159
164
|
);
|
|
160
165
|
|
|
161
|
-
if (
|
|
166
|
+
if (hasNewSessionCookie || authDetected) {
|
|
162
167
|
// Grace period: 4 additional polls at 2s each (~8s total)
|
|
163
168
|
// Allows time for MFA, CAPTCHAs, and post-login redirects
|
|
164
169
|
for (let grace = 0; grace < 4; grace++) {
|
package/src/capture/session.ts
CHANGED
|
@@ -75,13 +75,8 @@ export class CaptureSession {
|
|
|
75
75
|
|
|
76
76
|
this.setupResponseListener();
|
|
77
77
|
|
|
78
|
-
// Auto-timeout to prevent leaked browsers (
|
|
79
|
-
|
|
80
|
-
this.timeoutTimer = setTimeout(() => {
|
|
81
|
-
this.expired = true;
|
|
82
|
-
this.cleanup().catch(() => {});
|
|
83
|
-
}, timeoutMs);
|
|
84
|
-
if (this.timeoutTimer.unref) this.timeoutTimer.unref();
|
|
78
|
+
// Auto-timeout to prevent leaked browsers (resets on each interaction)
|
|
79
|
+
this.resetTimeout();
|
|
85
80
|
|
|
86
81
|
await this.page.goto(this.targetUrl, { waitUntil: 'domcontentloaded' });
|
|
87
82
|
return this.takeSnapshot();
|
|
@@ -92,6 +87,9 @@ export class CaptureSession {
|
|
|
92
87
|
if (this.closed) return { success: false, error: 'Session closed', snapshot: this.emptySnapshot() };
|
|
93
88
|
if (!this.page) return { success: false, error: 'Session not started', snapshot: this.emptySnapshot() };
|
|
94
89
|
|
|
90
|
+
// Reset timeout on each interaction — active sessions aren't leaked browsers
|
|
91
|
+
this.resetTimeout();
|
|
92
|
+
|
|
95
93
|
try {
|
|
96
94
|
switch (action.action) {
|
|
97
95
|
case 'snapshot':
|
|
@@ -468,6 +466,17 @@ export class CaptureSession {
|
|
|
468
466
|
};
|
|
469
467
|
}
|
|
470
468
|
|
|
469
|
+
/** Reset the auto-timeout timer (called on each interaction to prevent premature close) */
|
|
470
|
+
private resetTimeout(): void {
|
|
471
|
+
if (this.timeoutTimer) clearTimeout(this.timeoutTimer);
|
|
472
|
+
const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
473
|
+
this.timeoutTimer = setTimeout(() => {
|
|
474
|
+
this.expired = true;
|
|
475
|
+
this.cleanup().catch(() => {});
|
|
476
|
+
}, timeoutMs);
|
|
477
|
+
if (this.timeoutTimer.unref) this.timeoutTimer.unref();
|
|
478
|
+
}
|
|
479
|
+
|
|
471
480
|
private async cleanup(): Promise<void> {
|
|
472
481
|
if (this.closed) return;
|
|
473
482
|
this.closed = true;
|