vikarshana commited on
Commit
3909b11
·
verified ·
1 Parent(s): fb94bcc

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +68 -104
server.js CHANGED
@@ -23,123 +23,87 @@ app.use((req, res, next) => {
23
  }
24
  });
25
 
26
-
27
- async function captureDirectDownloadLink(url, opts = {}) {
28
- const { chromePath = '/opt/google/chrome/chrome', headless = 'new', waitForButtonMs = 60000 } = opts;
29
- let browser = null;
30
- let page = null;
31
-
32
- try {
33
- browser = await puppeteer.launch({
34
- executablePath: chromePath,
35
- headless,
36
- args: ['--disable-web-security', '--disable-gpu'],
37
- });
38
-
39
- page = await browser.newPage();
40
- await page.setViewport({ width: 1280, height: 900 });
41
- await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
42
-
43
- await page.evaluateOnNewDocument(() => {
44
- Object.defineProperty(navigator, 'webdriver', { get: () => false });
45
- Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3] });
46
- Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
47
- window.chrome = { runtime: {} };
48
- });
49
-
50
- await page.setRequestInterception(true);
51
- page.on('request', req => {
52
- const rt = req.resourceType();
53
- if (['image', 'stylesheet', 'font', 'media'].includes(rt)) req.abort();
54
- else req.continue();
55
- });
56
-
57
- await page.goto(url, { waitUntil: 'load', timeout: 60000 });
58
- await page.waitForFunction(() => document.readyState === 'complete', { timeout: 30000 }).catch(() => {});
59
-
60
- const directBtnId = await page.evaluate(() => {
61
- const btns = Array.from(document.querySelectorAll('button.direct-download'));
62
- const visibleBtns = btns.filter(b => {
63
- const r = b.getBoundingClientRect();
64
- return r.width > 0 && r.height > 0;
65
  });
66
- return visibleBtns.length > 1 ? visibleBtns[1].id : visibleBtns[0].id
67
- });
68
-
69
 
70
- if (!directBtnId) throw new Error('No direct-download button found!');
71
- console.log('Found visible direct button:', directBtnId);
72
-
73
- const [newPage] = await Promise.all([
74
- new Promise(resolve => {
75
- browser.once("targetcreated", async target => {
76
- try {
77
- const popup = await target.page();
78
- resolve(popup);
79
- } catch {
80
- resolve(null);
81
- }
 
 
 
 
 
 
 
 
 
 
82
  });
83
- }),
84
- page.evaluate(id => document.getElementById(id).click(), directBtnId),
85
- ]);
86
-
87
- let finalUrl;
88
-
89
- if (newPage) {
90
- await newPage.waitForLoadState?.("load").catch(() => {}); // wait until page is loaded
91
- finalUrl = newPage.url();
92
- console.log("✅ Captured new tab URL:", finalUrl);
93
- } else {
94
- throw new Error("No new tab detected after clicking button!");
95
- }
96
 
97
- await browser.close();
 
98
 
99
- if (!finalUrl) {
100
- throw new Error("Redirected download URL not captured");
101
- }
102
 
103
- return { success: true, url: finalUrl };;
 
104
 
105
- } catch (err) {
106
- console.error('captureDirectDownloadLink error:', err);
107
- if (page) try { await page.close(); } catch {}
108
- if (browser) try { await browser.close(); } catch {}
109
- return { success: false, error: String(err.message || err) };
110
- }
111
  }
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
- app.get('/api/bypass', async (req, res) => {
 
115
  const { url } = req.query;
116
- if (!url) return res.status(400).json({ error: 'URL is required' });
117
-
118
- try {
119
- const result = await captureDirectDownloadLink(url, {
120
- chromePath: '/opt/google/chrome/chrome',
121
- headless: 'new',
122
- buttonSelector: '#gdriveButton',
123
- fallbackSelector: '.google-download',
124
- waitForButtonMs: 60000,
125
- waitForPostMs: 20000,
126
- });
127
 
128
- if (!result.success) {
129
- return res.status(500).json({ error: result.error || 'failed' });
130
- }
131
-
132
- // Return cookie header and payload
133
- return res.json({
134
- url: result
135
- });
136
- } catch (err) {
137
- console.error('/api/bypass error:', err);
138
- return res.status(500).json({ error: 'Internal error' });
139
- }
140
  });
141
-
142
-
143
  // 健康检查端点
144
  app.get('/', (req, res) => {
145
  res.json({ status: 'hii', timestamp: new Date().toISOString() });
 
23
  }
24
  });
25
 
26
+ const http = require('http');
27
+ const WebSocket = require('ws');
28
+
29
+ const server = http.createServer(app);
30
+ const wss = new WebSocket.Server({ server });
31
+
32
+ const sessions = {};
33
+
34
+ async function launchRemoteBrowser(url) {
35
+ const browser = await puppeteer.launch({
36
+ executablePath: '/opt/google/chrome/chrome',
37
+ headless: false, // visible live browser
38
+ args: [
39
+ '--disable-web-security',
40
+ '--disable-gpu',
41
+ '--no-sandbox',
42
+ '--disable-blink-features=AutomationControlled'
43
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  });
 
 
 
45
 
46
+ const page = (await browser.pages())[0] || await browser.newPage();
47
+
48
+ await page.setViewport({ width: 1280, height: 900 });
49
+ await page.setUserAgent(
50
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
51
+ );
52
+
53
+ // Anti-bot / anti-devtools bypass
54
+ await page.evaluateOnNewDocument(() => {
55
+ Object.defineProperty(navigator, 'webdriver', { get: () => false });
56
+ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3] });
57
+ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
58
+ window.chrome = { runtime: {} };
59
+ window.console.debug = () => {};
60
+ window.console.log = () => {};
61
+ Object.defineProperty(window, 'outerWidth', { get: () => 1920 });
62
+ Object.defineProperty(window, 'outerHeight', { get: () => 1080 });
63
+ Object.defineProperty(window, 'innerWidth', { get: () => 1920 });
64
+ Object.defineProperty(window, 'innerHeight', { get: () => 1080 });
65
+ ['oncontextmenu', 'onkeydown', 'onkeyup', 'onbeforeunload'].forEach(e => window[e] = null);
66
+ Object.keys(window).forEach(k => {
67
+ if (k.toLowerCase().includes('disable') || k.toLowerCase().includes('devtool')) window[k] = () => {};
68
  });
69
+ });
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
+ await page.setRequestInterception(true);
72
+ page.on('request', req => req.continue()); // allow all requests
73
 
74
+ await page.goto(url, { waitUntil: 'load', timeout: 60000 });
 
 
75
 
76
+ const sessionId = Math.random().toString(36).substring(2, 12);
77
+ sessions[sessionId] = { browser, page };
78
 
79
+ return sessionId;
 
 
 
 
 
80
  }
81
 
82
+ // Serve web page for remote interaction
83
+ app.get('/remote/:sessionId', (req, res) => {
84
+ const { sessionId } = req.params;
85
+ if (!sessions[sessionId]) return res.status(404).send('Session not found');
86
+
87
+ res.send(`
88
+ <html>
89
+ <body>
90
+ <h2>Remote Live Browser</h2>
91
+ <p>Session ID: ${sessionId}</p>
92
+ <p>Use the WebSocket connection to control the browser live.</p>
93
+ <p>Note: This requires a WebRTC/noVNC setup for full interaction in real deployments.</p>
94
+ </body>
95
+ </html>
96
+ `);
97
+ });
98
 
99
+ // API endpoint to start a live browser session
100
+ app.get('/api/live', async (req, res) => {
101
  const { url } = req.query;
102
+ if (!url) return res.status(400).send('URL is required');
 
 
 
 
 
 
 
 
 
 
103
 
104
+ const sessionId = await launchRemoteBrowser(url);
105
+ res.send(`✅ Live browser launched. Open <a href="/remote/${sessionId}">this link</a> to interact remotely.`);
 
 
 
 
 
 
 
 
 
 
106
  });
 
 
107
  // 健康检查端点
108
  app.get('/', (req, res) => {
109
  res.json({ status: 'hii', timestamp: new Date().toISOString() });