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>
This commit is contained in:
Kelly
2025-12-05 04:07:31 -07:00
parent d2d44d2aeb
commit d91c55a344
3115 changed files with 5755 additions and 719 deletions

View File

@@ -0,0 +1,110 @@
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();