@vulcn/driver-browser 0.2.0 → 0.4.0
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/dist/index.cjs +749 -194
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +180 -22
- package/dist/index.d.ts +180 -22
- package/dist/index.js +743 -193
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { RecordOptions, RecordingHandle, Session, RunContext, RunResult, CrawlOptions, VulcnDriver } from '@vulcn/engine';
|
|
3
|
-
import { Browser } from 'playwright';
|
|
2
|
+
import { RecordOptions, RecordingHandle, Session, RunContext, RunResult, CapturedRequest, CrawlOptions, Finding, PayloadCategory, RuntimePayload, FormCredentials, VulcnDriver } from '@vulcn/engine';
|
|
3
|
+
import { Browser, Page, BrowserContext } from 'playwright';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Browser Recorder Implementation
|
|
@@ -32,33 +32,31 @@ declare class BrowserRecorder {
|
|
|
32
32
|
*
|
|
33
33
|
* Replays browser sessions with security payloads.
|
|
34
34
|
* Uses plugin hooks for detection.
|
|
35
|
+
*
|
|
36
|
+
* v2: Persistent browser with in-page payload cycling.
|
|
37
|
+
* - ONE browser for the entire scan (not per-session)
|
|
38
|
+
* - Uses page.goBack() between payloads instead of full page.goto()
|
|
39
|
+
* - Falls back to full navigation when goBack() fails
|
|
40
|
+
* - 5-10x faster on SPAs, same speed on simple sites
|
|
35
41
|
*/
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* Browser Runner - replays sessions with payloads
|
|
45
|
+
*
|
|
46
|
+
* Supports two modes:
|
|
47
|
+
* 1. Self-managed browser: launches its own browser (backward compat)
|
|
48
|
+
* 2. Shared browser: receives a browser instance via RunOptions
|
|
49
|
+
*
|
|
50
|
+
* In both modes, payload cycling uses goBack() for speed.
|
|
39
51
|
*/
|
|
40
52
|
declare class BrowserRunner {
|
|
41
53
|
/**
|
|
42
|
-
* Execute a session with security payloads
|
|
43
|
-
*/
|
|
44
|
-
static execute(session: Session, ctx: RunContext): Promise<RunResult>;
|
|
45
|
-
/**
|
|
46
|
-
* Replay session steps with payload injected at target step
|
|
54
|
+
* Execute a session with security payloads.
|
|
47
55
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* clicking submit) must still execute so the payload reaches the server
|
|
51
|
-
* and gets reflected back in the response.
|
|
56
|
+
* If ctx.options.browser is provided, reuses that browser (persistent mode).
|
|
57
|
+
* Otherwise, launches and closes its own browser (standalone mode).
|
|
52
58
|
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Check for payload reflection in page content
|
|
56
|
-
*/
|
|
57
|
-
private static checkReflection;
|
|
58
|
-
/**
|
|
59
|
-
* Determine severity based on vulnerability category
|
|
60
|
-
*/
|
|
61
|
-
private static getSeverity;
|
|
59
|
+
static execute(session: Session, ctx: RunContext): Promise<RunResult>;
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
/**
|
|
@@ -105,6 +103,7 @@ declare function checkBrowsers(): Promise<{
|
|
|
105
103
|
* - Links to follow for deeper crawling
|
|
106
104
|
*
|
|
107
105
|
* Outputs Session[] that are directly compatible with BrowserRunner.
|
|
106
|
+
* Also generates CapturedRequest[] metadata for Tier 1 HTTP fast scanning.
|
|
108
107
|
*
|
|
109
108
|
* This is the "auto-record" mode — instead of a human clicking around,
|
|
110
109
|
* the crawler automatically discovers injection points.
|
|
@@ -123,12 +122,171 @@ interface BrowserCrawlConfig {
|
|
|
123
122
|
height: number;
|
|
124
123
|
};
|
|
125
124
|
}
|
|
125
|
+
/** Result from crawling — sessions for browser replay + requests for HTTP scanning */
|
|
126
|
+
interface CrawlResult {
|
|
127
|
+
sessions: Session[];
|
|
128
|
+
capturedRequests: CapturedRequest[];
|
|
129
|
+
}
|
|
126
130
|
/**
|
|
127
131
|
* Crawl a URL and generate sessions.
|
|
128
132
|
*
|
|
129
133
|
* This is called by the browser driver's recorder.crawl() method.
|
|
134
|
+
* Returns both Session[] for Tier 2 browser replay and
|
|
135
|
+
* CapturedRequest[] for Tier 1 HTTP fast scanning.
|
|
136
|
+
*/
|
|
137
|
+
declare function crawlAndBuildSessions(config: BrowserCrawlConfig, options?: CrawlOptions): Promise<CrawlResult>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* HTTP Scanner — Tier 1 Fast Scan
|
|
141
|
+
*
|
|
142
|
+
* Replays captured HTTP requests via fetch() instead of Playwright.
|
|
143
|
+
* Substitutes security payloads into injectable form fields and checks
|
|
144
|
+
* the response body for payload reflection or error patterns.
|
|
145
|
+
*
|
|
146
|
+
* Speed: ~50ms per payload (vs 2-5s for browser replay)
|
|
147
|
+
*
|
|
148
|
+
* Catches:
|
|
149
|
+
* - Reflected XSS (payload appears in response body)
|
|
150
|
+
* - Error-based SQLi (SQL error patterns in response)
|
|
151
|
+
* - Server-side reflection of any payload
|
|
152
|
+
*
|
|
153
|
+
* Misses:
|
|
154
|
+
* - DOM-based XSS (requires JS execution)
|
|
155
|
+
* - Client-side state bugs
|
|
156
|
+
* - CSP-blocked attacks
|
|
157
|
+
*
|
|
158
|
+
* When reflection IS found, the finding is marked as `needsBrowserConfirmation`
|
|
159
|
+
* so the caller can escalate to Tier 2 for execution-based proof.
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
interface HttpScanResult {
|
|
163
|
+
/** Total HTTP requests sent */
|
|
164
|
+
requestsSent: number;
|
|
165
|
+
/** How long the scan took (ms) */
|
|
166
|
+
duration: number;
|
|
167
|
+
/** Findings from reflection detection */
|
|
168
|
+
findings: Finding[];
|
|
169
|
+
/** Requests where reflection was found — should be escalated to Tier 2 */
|
|
170
|
+
reflectedRequests: ReflectedRequest[];
|
|
171
|
+
}
|
|
172
|
+
interface ReflectedRequest {
|
|
173
|
+
/** Original captured request */
|
|
174
|
+
request: CapturedRequest;
|
|
175
|
+
/** Payload that caused reflection */
|
|
176
|
+
payload: string;
|
|
177
|
+
/** Category of the payload */
|
|
178
|
+
category: PayloadCategory;
|
|
179
|
+
}
|
|
180
|
+
interface HttpScanOptions {
|
|
181
|
+
/** Request timeout in ms (default: 10000) */
|
|
182
|
+
timeout?: number;
|
|
183
|
+
/** Max concurrent requests (default: 10) */
|
|
184
|
+
concurrency?: number;
|
|
185
|
+
/** Cookie header to send with requests (for auth) */
|
|
186
|
+
cookies?: string;
|
|
187
|
+
/** Extra headers to send */
|
|
188
|
+
headers?: Record<string, string>;
|
|
189
|
+
/** Callback for progress reporting */
|
|
190
|
+
onProgress?: (completed: number, total: number) => void;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Run Tier 1 HTTP-level scan on captured requests.
|
|
194
|
+
*
|
|
195
|
+
* For each CapturedRequest × each payload:
|
|
196
|
+
* 1. Substitute the payload into the injectable field
|
|
197
|
+
* 2. Send via fetch()
|
|
198
|
+
* 3. Check response body for reflection patterns
|
|
199
|
+
* 4. If reflected, add finding + mark for Tier 2 escalation
|
|
200
|
+
*/
|
|
201
|
+
declare function httpScan(requests: CapturedRequest[], payloads: RuntimePayload[], options?: HttpScanOptions): Promise<HttpScanResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Convert discovered forms into CapturedRequest metadata.
|
|
204
|
+
*
|
|
205
|
+
* Called by the crawler after form discovery. Each injectable form
|
|
206
|
+
* produces one CapturedRequest per injectable input field.
|
|
207
|
+
*/
|
|
208
|
+
declare function buildCapturedRequests(forms: Array<{
|
|
209
|
+
pageUrl: string;
|
|
210
|
+
action: string;
|
|
211
|
+
method: string;
|
|
212
|
+
inputs: Array<{
|
|
213
|
+
name: string;
|
|
214
|
+
injectable: boolean;
|
|
215
|
+
type: string;
|
|
216
|
+
}>;
|
|
217
|
+
sessionName: string;
|
|
218
|
+
}>): CapturedRequest[];
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Login Form Auto-Detection & Auth Replay
|
|
222
|
+
*
|
|
223
|
+
* Detects login forms on a page and fills them with credentials.
|
|
224
|
+
* After login, captures the browser storage state (cookies + localStorage)
|
|
225
|
+
* for re-use in subsequent scans.
|
|
226
|
+
*
|
|
227
|
+
* Detection strategy:
|
|
228
|
+
* 1. Find forms with a password input (strongest signal)
|
|
229
|
+
* 2. Find username field via heuristics (name, id, autocomplete, type)
|
|
230
|
+
* 3. Find submit button
|
|
231
|
+
* 4. Fall back to custom selectors from credentials
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
interface LoginForm {
|
|
235
|
+
/** Username input selector */
|
|
236
|
+
usernameSelector: string;
|
|
237
|
+
/** Password input selector */
|
|
238
|
+
passwordSelector: string;
|
|
239
|
+
/** Submit button selector (may be null if not found) */
|
|
240
|
+
submitSelector: string | null;
|
|
241
|
+
/** Whether the form was detected automatically */
|
|
242
|
+
autoDetected: boolean;
|
|
243
|
+
}
|
|
244
|
+
interface LoginResult {
|
|
245
|
+
/** Whether login succeeded */
|
|
246
|
+
success: boolean;
|
|
247
|
+
/** Message for logging */
|
|
248
|
+
message: string;
|
|
249
|
+
/** Playwright storage state JSON (cookies + localStorage) */
|
|
250
|
+
storageState?: string;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Auto-detect a login form on the current page.
|
|
254
|
+
*
|
|
255
|
+
* Strategy:
|
|
256
|
+
* 1. Find `<form>` elements containing an `input[type="password"]`
|
|
257
|
+
* 2. Within that form, find the username field using heuristics
|
|
258
|
+
* 3. Find the submit button
|
|
259
|
+
*
|
|
260
|
+
* Falls back to page-wide search if no enclosing <form> is found.
|
|
261
|
+
*/
|
|
262
|
+
declare function detectLoginForm(page: Page): Promise<LoginForm | null>;
|
|
263
|
+
/**
|
|
264
|
+
* Perform login using detected form or custom selectors.
|
|
265
|
+
*
|
|
266
|
+
* Flow:
|
|
267
|
+
* 1. Navigate to login URL (or target URL)
|
|
268
|
+
* 2. Detect login form (or use custom selectors from credentials)
|
|
269
|
+
* 3. Fill username + password
|
|
270
|
+
* 4. Submit form
|
|
271
|
+
* 5. Wait for navigation
|
|
272
|
+
* 6. Check for logged-in indicator
|
|
273
|
+
* 7. Capture storage state
|
|
274
|
+
*/
|
|
275
|
+
declare function performLogin(page: Page, context: BrowserContext, credentials: FormCredentials, options: {
|
|
276
|
+
targetUrl: string;
|
|
277
|
+
loggedInIndicator?: string;
|
|
278
|
+
loggedOutIndicator?: string;
|
|
279
|
+
}): Promise<LoginResult>;
|
|
280
|
+
/**
|
|
281
|
+
* Check if the current session is still alive.
|
|
282
|
+
*
|
|
283
|
+
* Used during long-running scans to detect session expiry
|
|
284
|
+
* and trigger re-authentication.
|
|
130
285
|
*/
|
|
131
|
-
declare function
|
|
286
|
+
declare function checkSessionAlive(page: Page, config: {
|
|
287
|
+
loggedInIndicator?: string;
|
|
288
|
+
loggedOutIndicator?: string;
|
|
289
|
+
}): Promise<boolean>;
|
|
132
290
|
|
|
133
291
|
/**
|
|
134
292
|
* @vulcn/driver-browser
|
|
@@ -334,4 +492,4 @@ type BrowserStep = z.infer<typeof BrowserStepSchema>;
|
|
|
334
492
|
*/
|
|
335
493
|
declare const browserDriver: VulcnDriver;
|
|
336
494
|
|
|
337
|
-
export { BROWSER_STEP_TYPES, type BrowserConfig, BrowserRecorder, BrowserRunner, type BrowserStep, BrowserStepSchema, type BrowserStepType, checkBrowsers, configSchema, crawlAndBuildSessions, browserDriver as default, installBrowsers, launchBrowser };
|
|
495
|
+
export { BROWSER_STEP_TYPES, type BrowserConfig, BrowserRecorder, BrowserRunner, type BrowserStep, BrowserStepSchema, type BrowserStepType, type CrawlResult, type HttpScanOptions, type HttpScanResult, type LoginForm, type LoginResult, type ReflectedRequest, buildCapturedRequests, checkBrowsers, checkSessionAlive, configSchema, crawlAndBuildSessions, browserDriver as default, detectLoginForm, httpScan, installBrowsers, launchBrowser, performLogin };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { RecordOptions, RecordingHandle, Session, RunContext, RunResult, CrawlOptions, VulcnDriver } from '@vulcn/engine';
|
|
3
|
-
import { Browser } from 'playwright';
|
|
2
|
+
import { RecordOptions, RecordingHandle, Session, RunContext, RunResult, CapturedRequest, CrawlOptions, Finding, PayloadCategory, RuntimePayload, FormCredentials, VulcnDriver } from '@vulcn/engine';
|
|
3
|
+
import { Browser, Page, BrowserContext } from 'playwright';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Browser Recorder Implementation
|
|
@@ -32,33 +32,31 @@ declare class BrowserRecorder {
|
|
|
32
32
|
*
|
|
33
33
|
* Replays browser sessions with security payloads.
|
|
34
34
|
* Uses plugin hooks for detection.
|
|
35
|
+
*
|
|
36
|
+
* v2: Persistent browser with in-page payload cycling.
|
|
37
|
+
* - ONE browser for the entire scan (not per-session)
|
|
38
|
+
* - Uses page.goBack() between payloads instead of full page.goto()
|
|
39
|
+
* - Falls back to full navigation when goBack() fails
|
|
40
|
+
* - 5-10x faster on SPAs, same speed on simple sites
|
|
35
41
|
*/
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* Browser Runner - replays sessions with payloads
|
|
45
|
+
*
|
|
46
|
+
* Supports two modes:
|
|
47
|
+
* 1. Self-managed browser: launches its own browser (backward compat)
|
|
48
|
+
* 2. Shared browser: receives a browser instance via RunOptions
|
|
49
|
+
*
|
|
50
|
+
* In both modes, payload cycling uses goBack() for speed.
|
|
39
51
|
*/
|
|
40
52
|
declare class BrowserRunner {
|
|
41
53
|
/**
|
|
42
|
-
* Execute a session with security payloads
|
|
43
|
-
*/
|
|
44
|
-
static execute(session: Session, ctx: RunContext): Promise<RunResult>;
|
|
45
|
-
/**
|
|
46
|
-
* Replay session steps with payload injected at target step
|
|
54
|
+
* Execute a session with security payloads.
|
|
47
55
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* clicking submit) must still execute so the payload reaches the server
|
|
51
|
-
* and gets reflected back in the response.
|
|
56
|
+
* If ctx.options.browser is provided, reuses that browser (persistent mode).
|
|
57
|
+
* Otherwise, launches and closes its own browser (standalone mode).
|
|
52
58
|
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Check for payload reflection in page content
|
|
56
|
-
*/
|
|
57
|
-
private static checkReflection;
|
|
58
|
-
/**
|
|
59
|
-
* Determine severity based on vulnerability category
|
|
60
|
-
*/
|
|
61
|
-
private static getSeverity;
|
|
59
|
+
static execute(session: Session, ctx: RunContext): Promise<RunResult>;
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
/**
|
|
@@ -105,6 +103,7 @@ declare function checkBrowsers(): Promise<{
|
|
|
105
103
|
* - Links to follow for deeper crawling
|
|
106
104
|
*
|
|
107
105
|
* Outputs Session[] that are directly compatible with BrowserRunner.
|
|
106
|
+
* Also generates CapturedRequest[] metadata for Tier 1 HTTP fast scanning.
|
|
108
107
|
*
|
|
109
108
|
* This is the "auto-record" mode — instead of a human clicking around,
|
|
110
109
|
* the crawler automatically discovers injection points.
|
|
@@ -123,12 +122,171 @@ interface BrowserCrawlConfig {
|
|
|
123
122
|
height: number;
|
|
124
123
|
};
|
|
125
124
|
}
|
|
125
|
+
/** Result from crawling — sessions for browser replay + requests for HTTP scanning */
|
|
126
|
+
interface CrawlResult {
|
|
127
|
+
sessions: Session[];
|
|
128
|
+
capturedRequests: CapturedRequest[];
|
|
129
|
+
}
|
|
126
130
|
/**
|
|
127
131
|
* Crawl a URL and generate sessions.
|
|
128
132
|
*
|
|
129
133
|
* This is called by the browser driver's recorder.crawl() method.
|
|
134
|
+
* Returns both Session[] for Tier 2 browser replay and
|
|
135
|
+
* CapturedRequest[] for Tier 1 HTTP fast scanning.
|
|
136
|
+
*/
|
|
137
|
+
declare function crawlAndBuildSessions(config: BrowserCrawlConfig, options?: CrawlOptions): Promise<CrawlResult>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* HTTP Scanner — Tier 1 Fast Scan
|
|
141
|
+
*
|
|
142
|
+
* Replays captured HTTP requests via fetch() instead of Playwright.
|
|
143
|
+
* Substitutes security payloads into injectable form fields and checks
|
|
144
|
+
* the response body for payload reflection or error patterns.
|
|
145
|
+
*
|
|
146
|
+
* Speed: ~50ms per payload (vs 2-5s for browser replay)
|
|
147
|
+
*
|
|
148
|
+
* Catches:
|
|
149
|
+
* - Reflected XSS (payload appears in response body)
|
|
150
|
+
* - Error-based SQLi (SQL error patterns in response)
|
|
151
|
+
* - Server-side reflection of any payload
|
|
152
|
+
*
|
|
153
|
+
* Misses:
|
|
154
|
+
* - DOM-based XSS (requires JS execution)
|
|
155
|
+
* - Client-side state bugs
|
|
156
|
+
* - CSP-blocked attacks
|
|
157
|
+
*
|
|
158
|
+
* When reflection IS found, the finding is marked as `needsBrowserConfirmation`
|
|
159
|
+
* so the caller can escalate to Tier 2 for execution-based proof.
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
interface HttpScanResult {
|
|
163
|
+
/** Total HTTP requests sent */
|
|
164
|
+
requestsSent: number;
|
|
165
|
+
/** How long the scan took (ms) */
|
|
166
|
+
duration: number;
|
|
167
|
+
/** Findings from reflection detection */
|
|
168
|
+
findings: Finding[];
|
|
169
|
+
/** Requests where reflection was found — should be escalated to Tier 2 */
|
|
170
|
+
reflectedRequests: ReflectedRequest[];
|
|
171
|
+
}
|
|
172
|
+
interface ReflectedRequest {
|
|
173
|
+
/** Original captured request */
|
|
174
|
+
request: CapturedRequest;
|
|
175
|
+
/** Payload that caused reflection */
|
|
176
|
+
payload: string;
|
|
177
|
+
/** Category of the payload */
|
|
178
|
+
category: PayloadCategory;
|
|
179
|
+
}
|
|
180
|
+
interface HttpScanOptions {
|
|
181
|
+
/** Request timeout in ms (default: 10000) */
|
|
182
|
+
timeout?: number;
|
|
183
|
+
/** Max concurrent requests (default: 10) */
|
|
184
|
+
concurrency?: number;
|
|
185
|
+
/** Cookie header to send with requests (for auth) */
|
|
186
|
+
cookies?: string;
|
|
187
|
+
/** Extra headers to send */
|
|
188
|
+
headers?: Record<string, string>;
|
|
189
|
+
/** Callback for progress reporting */
|
|
190
|
+
onProgress?: (completed: number, total: number) => void;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Run Tier 1 HTTP-level scan on captured requests.
|
|
194
|
+
*
|
|
195
|
+
* For each CapturedRequest × each payload:
|
|
196
|
+
* 1. Substitute the payload into the injectable field
|
|
197
|
+
* 2. Send via fetch()
|
|
198
|
+
* 3. Check response body for reflection patterns
|
|
199
|
+
* 4. If reflected, add finding + mark for Tier 2 escalation
|
|
200
|
+
*/
|
|
201
|
+
declare function httpScan(requests: CapturedRequest[], payloads: RuntimePayload[], options?: HttpScanOptions): Promise<HttpScanResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Convert discovered forms into CapturedRequest metadata.
|
|
204
|
+
*
|
|
205
|
+
* Called by the crawler after form discovery. Each injectable form
|
|
206
|
+
* produces one CapturedRequest per injectable input field.
|
|
207
|
+
*/
|
|
208
|
+
declare function buildCapturedRequests(forms: Array<{
|
|
209
|
+
pageUrl: string;
|
|
210
|
+
action: string;
|
|
211
|
+
method: string;
|
|
212
|
+
inputs: Array<{
|
|
213
|
+
name: string;
|
|
214
|
+
injectable: boolean;
|
|
215
|
+
type: string;
|
|
216
|
+
}>;
|
|
217
|
+
sessionName: string;
|
|
218
|
+
}>): CapturedRequest[];
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Login Form Auto-Detection & Auth Replay
|
|
222
|
+
*
|
|
223
|
+
* Detects login forms on a page and fills them with credentials.
|
|
224
|
+
* After login, captures the browser storage state (cookies + localStorage)
|
|
225
|
+
* for re-use in subsequent scans.
|
|
226
|
+
*
|
|
227
|
+
* Detection strategy:
|
|
228
|
+
* 1. Find forms with a password input (strongest signal)
|
|
229
|
+
* 2. Find username field via heuristics (name, id, autocomplete, type)
|
|
230
|
+
* 3. Find submit button
|
|
231
|
+
* 4. Fall back to custom selectors from credentials
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
interface LoginForm {
|
|
235
|
+
/** Username input selector */
|
|
236
|
+
usernameSelector: string;
|
|
237
|
+
/** Password input selector */
|
|
238
|
+
passwordSelector: string;
|
|
239
|
+
/** Submit button selector (may be null if not found) */
|
|
240
|
+
submitSelector: string | null;
|
|
241
|
+
/** Whether the form was detected automatically */
|
|
242
|
+
autoDetected: boolean;
|
|
243
|
+
}
|
|
244
|
+
interface LoginResult {
|
|
245
|
+
/** Whether login succeeded */
|
|
246
|
+
success: boolean;
|
|
247
|
+
/** Message for logging */
|
|
248
|
+
message: string;
|
|
249
|
+
/** Playwright storage state JSON (cookies + localStorage) */
|
|
250
|
+
storageState?: string;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Auto-detect a login form on the current page.
|
|
254
|
+
*
|
|
255
|
+
* Strategy:
|
|
256
|
+
* 1. Find `<form>` elements containing an `input[type="password"]`
|
|
257
|
+
* 2. Within that form, find the username field using heuristics
|
|
258
|
+
* 3. Find the submit button
|
|
259
|
+
*
|
|
260
|
+
* Falls back to page-wide search if no enclosing <form> is found.
|
|
261
|
+
*/
|
|
262
|
+
declare function detectLoginForm(page: Page): Promise<LoginForm | null>;
|
|
263
|
+
/**
|
|
264
|
+
* Perform login using detected form or custom selectors.
|
|
265
|
+
*
|
|
266
|
+
* Flow:
|
|
267
|
+
* 1. Navigate to login URL (or target URL)
|
|
268
|
+
* 2. Detect login form (or use custom selectors from credentials)
|
|
269
|
+
* 3. Fill username + password
|
|
270
|
+
* 4. Submit form
|
|
271
|
+
* 5. Wait for navigation
|
|
272
|
+
* 6. Check for logged-in indicator
|
|
273
|
+
* 7. Capture storage state
|
|
274
|
+
*/
|
|
275
|
+
declare function performLogin(page: Page, context: BrowserContext, credentials: FormCredentials, options: {
|
|
276
|
+
targetUrl: string;
|
|
277
|
+
loggedInIndicator?: string;
|
|
278
|
+
loggedOutIndicator?: string;
|
|
279
|
+
}): Promise<LoginResult>;
|
|
280
|
+
/**
|
|
281
|
+
* Check if the current session is still alive.
|
|
282
|
+
*
|
|
283
|
+
* Used during long-running scans to detect session expiry
|
|
284
|
+
* and trigger re-authentication.
|
|
130
285
|
*/
|
|
131
|
-
declare function
|
|
286
|
+
declare function checkSessionAlive(page: Page, config: {
|
|
287
|
+
loggedInIndicator?: string;
|
|
288
|
+
loggedOutIndicator?: string;
|
|
289
|
+
}): Promise<boolean>;
|
|
132
290
|
|
|
133
291
|
/**
|
|
134
292
|
* @vulcn/driver-browser
|
|
@@ -334,4 +492,4 @@ type BrowserStep = z.infer<typeof BrowserStepSchema>;
|
|
|
334
492
|
*/
|
|
335
493
|
declare const browserDriver: VulcnDriver;
|
|
336
494
|
|
|
337
|
-
export { BROWSER_STEP_TYPES, type BrowserConfig, BrowserRecorder, BrowserRunner, type BrowserStep, BrowserStepSchema, type BrowserStepType, checkBrowsers, configSchema, crawlAndBuildSessions, browserDriver as default, installBrowsers, launchBrowser };
|
|
495
|
+
export { BROWSER_STEP_TYPES, type BrowserConfig, BrowserRecorder, BrowserRunner, type BrowserStep, BrowserStepSchema, type BrowserStepType, type CrawlResult, type HttpScanOptions, type HttpScanResult, type LoginForm, type LoginResult, type ReflectedRequest, buildCapturedRequests, checkBrowsers, checkSessionAlive, configSchema, crawlAndBuildSessions, browserDriver as default, detectLoginForm, httpScan, installBrowsers, launchBrowser, performLogin };
|