Files
cannaiq/backend/archive/check-leaks.ts
Kelly d91c55a344 feat: Add stale process monitor, users route, landing page, archive old scripts
- Add backend stale process monitoring API (/api/stale-processes)
- Add users management route
- Add frontend landing page and stale process monitor UI on /scraper-tools
- Move old development scripts to backend/archive/
- Update frontend build with new features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 04:07:31 -07:00

111 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import { Pool } from 'pg';
puppeteer.use(StealthPlugin());
const pool = new Pool({
connectionString: 'postgresql://sail:password@localhost:5432/dutchie_menus'
});
async function check() {
let browser;
try {
const proxyResult = await pool.query(`SELECT host, port, protocol FROM proxies ORDER BY RANDOM() LIMIT 1`);
const proxy = proxyResult.rows[0];
browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox', `--proxy-server=${proxy.protocol}://${proxy.host}:${proxy.port}`]
});
const page = await browser.newPage();
await page.setUserAgent('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');
console.log('🔍 CHECKING FOR DATA LEAKS\n');
await page.goto('https://curaleaf.com/stores/curaleaf-dispensary-phoenix-airport/brands', {
waitUntil: 'networkidle2',
timeout: 60000
});
await page.waitForTimeout(5000);
// Check what browser exposes
const browserData = await page.evaluate(() => ({
// Automation detection
webdriver: navigator.webdriver,
hasHeadlessUA: /headless/i.test(navigator.userAgent),
// User agent
userAgent: navigator.userAgent,
// Chrome detection
hasChrome: typeof (window as any).chrome !== 'undefined',
chromeKeys: (window as any).chrome ? Object.keys((window as any).chrome) : [],
// Permissions
permissions: navigator.permissions ? 'exists' : 'missing',
// Languages
languages: navigator.languages,
language: navigator.language,
// Plugins
pluginCount: navigator.plugins.length,
// Platform
platform: navigator.platform,
// Screen
screenWidth: screen.width,
screenHeight: screen.height,
// JavaScript working?
jsWorking: true,
// Page content
title: document.title,
bodyLength: document.body.innerHTML.length,
hasReactRoot: document.getElementById('__next') !== null,
scriptTags: document.querySelectorAll('script').length
}));
console.log('📋 BROWSER FINGERPRINT:');
console.log('─'.repeat(60));
console.log('navigator.webdriver:', browserData.webdriver, browserData.webdriver ? '❌ LEAKED!' : '✅');
console.log('navigator.userAgent:', browserData.userAgent);
console.log('Has "headless" in UA:', browserData.hasHeadlessUA, browserData.hasHeadlessUA ? '❌' : '✅');
console.log('window.chrome exists:', browserData.hasChrome, browserData.hasChrome ? '✅' : '❌ SUSPICIOUS');
console.log('Chrome keys:', browserData.chromeKeys.join(', '));
console.log('Languages:', browserData.languages);
console.log('Platform:', browserData.platform);
console.log('Plugins:', browserData.pluginCount);
console.log('\n📄 PAGE STATE:');
console.log('─'.repeat(60));
console.log('JavaScript executing:', browserData.jsWorking ? '✅ YES' : '❌ NO');
console.log('Page title:', `"${browserData.title}"`);
console.log('Body HTML size:', browserData.bodyLength, 'chars');
console.log('React root exists:', browserData.hasReactRoot ? '✅' : '❌');
console.log('Script tags:', browserData.scriptTags);
if (browserData.bodyLength < 1000) {
console.log('\n⚠ PROBLEM: Body too small! JS likely failed to load/execute');
}
if (!browserData.title) {
console.log('⚠️ PROBLEM: No page title! Page didn\'t render');
}
} catch (error: any) {
console.error('❌', error.message);
} finally {
if (browser) await browser.close();
await pool.end();
}
}
check();