( browserName: string, domains: string[], profile = 'Default', )
| 245 | * Decrypt and return Playwright-compatible cookies for specific domains. |
| 246 | */ |
| 247 | export async function importCookies( |
| 248 | browserName: string, |
| 249 | domains: string[], |
| 250 | profile = 'Default', |
| 251 | ): Promise<ImportResult> { |
| 252 | if (domains.length === 0) return { cookies: [], count: 0, failed: 0, domainCounts: {} }; |
| 253 | |
| 254 | const browser = resolveBrowser(browserName); |
| 255 | const match = getBrowserMatch(browser, profile); |
| 256 | const derivedKeys = await getDerivedKeys(match); |
| 257 | const db = openDb(match.dbPath, browser.name); |
| 258 | |
| 259 | try { |
| 260 | const now = chromiumNow(); |
| 261 | // Parameterized query — no SQL injection |
| 262 | const placeholders = domains.map(() => '?').join(','); |
| 263 | const rows = db.query( |
| 264 | `SELECT host_key, name, value, encrypted_value, path, expires_utc, |
| 265 | is_secure, is_httponly, has_expires, samesite |
| 266 | FROM cookies |
| 267 | WHERE host_key IN (${placeholders}) |
| 268 | AND (has_expires = 0 OR expires_utc > ?) |
| 269 | ORDER BY host_key, name` |
| 270 | ).all(...domains, now) as RawCookie[]; |
| 271 | |
| 272 | const cookies: PlaywrightCookie[] = []; |
| 273 | let failed = 0; |
| 274 | const domainCounts: Record<string, number> = {}; |
| 275 | |
| 276 | for (const row of rows) { |
| 277 | try { |
| 278 | const value = decryptCookieValue(row, derivedKeys, match.platform); |
| 279 | const cookie = toPlaywrightCookie(row, value); |
| 280 | cookies.push(cookie); |
| 281 | domainCounts[row.host_key] = (domainCounts[row.host_key] || 0) + 1; |
| 282 | } catch { |
| 283 | failed++; |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | return { cookies, count: cookies.length, failed, domainCounts }; |
| 288 | } finally { |
| 289 | db.close(); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | // ─── Internal: Browser Resolution ─────────────────────────────── |
| 294 |
no test coverage detected