| import { format as formatBytes } from 'bytes' |
| import express from 'express' |
| import { fileTypeFromBuffer } from 'file-type' |
| import morgan from 'morgan' |
| import pg from 'puppeteer-ghost' |
| import * as prb from 'puppeteer-real-browser' |
| import serveIndex from 'serve-index' |
|
|
| import { spawn } from 'node:child_process' |
| import { createWriteStream } from 'node:fs' |
| import { writeFile } from 'node:fs/promises' |
| import { tmpdir } from 'node:os' |
| import { env } from 'node:process' |
| import { setTimeout } from 'node:timers/promises' |
| import { format } from 'node:util' |
|
|
| const app = express() |
| app.enable('trust proxy') |
|
|
| const limitSize = '1000mb' |
| app.set('json spaces', 2) |
| app.use(express.json({ limit: limitSize })) |
| app.use(express.urlencoded({ |
| extended: true, |
| limit: limitSize |
| })) |
| app.use(morgan('dev')) |
|
|
| const tmpDir = tmpdir() |
| app.use( |
| tmpDir, |
| express.static(tmpDir), |
| serveIndex( |
| tmpDir, |
| { hidden: true, icons: true } |
| ) |
| ) |
|
|
| const isBase64 = (str) => { |
| try { |
| return btoa(atob(str)) === str |
| } catch { |
| return false |
| } |
| } |
|
|
| app.all('/', async (req, res) => { |
| try { |
| if (req.method !== 'POST') return res |
| .status(405) |
| .json({ msg: 'Hello World' }) |
|
|
| const { file } = req.body |
| if (!isBase64(file)) return res |
| .status(400) |
| .json({ |
| err: true, |
| msg: 'Bad Request' |
| }) |
|
|
| const buffer = Buffer.from(file, 'base64') |
| const type = |
| await fileTypeFromBuffer(buffer) || |
| { |
| mime: 'application/octet-stream', |
| ext: 'bin' |
| } |
|
|
| const name = format( |
| '%s/%s-%s.%s', |
| tmpDir, |
| type.mime.split('/')[0], |
| Math.random().toString(36).slice(2), |
| type.ext |
| ) |
| await writeFile(name, buffer) |
|
|
| const bytes = buffer.length |
| res.json({ |
| name: name.split('/').pop(), |
| size: { |
| bytes, |
| readable: formatBytes( |
| bytes, |
| { unitSeparator: ' ' } |
| ), |
| }, |
| url: format( |
| '%s://%s', |
| req.protocol, |
| req.host + name |
| ) |
| }) |
| } catch (e) { |
| console.error(e) |
| res |
| .status(500) |
| .json({ |
| err: true, |
| msg: format(e?.message || e) |
| }) |
| } |
| }) |
|
|
| |
| app.get( |
| '/shell', |
| (req, res, next) => { |
| console.log( |
| req.headers, |
| req.get('user-agent') |
| ) |
| |
| |
| next() |
| }, |
| async (req, res) => { |
| const [cmd = 'w', ...args] = req |
| .query |
| .cmd |
| .trim() |
| .split(' ') |
| const file = format( |
| '%s/%s.log' |
| tmpDir, |
| Date.now() |
| ) |
| const log = createWriteStream( |
| file, |
| { flags: 'a' } |
| ) |
| const child = spawn( |
| cmd, |
| args, |
| { |
| detached: true, |
| stdio: ['ignore', log, log] |
| } |
| ) |
| child.unref() |
| res.redirect(file) |
| } |
| ) |
|
|
| const executablePath = env.CHROME_BIN |
| app.get('/ss', async (req, res) => { |
| const { |
| delay = 0, |
| full = false, |
| mode = 'ghost', |
| transparent = false, |
| url = 'https://example.com' |
| } = req.query |
| if (String(url).includes('whatsapp.com')) |
| return res.redirect('/') |
|
|
| const isGhost = /^ghost$/i.test(mode) |
| const ctx = isGhost ? |
| await pg.launch({ |
| executablePath, |
| headless: 'new' |
| }) : |
| await prb.connect({ |
| customConfig: { executablePath }, |
| disableXvfb: true, |
| headless: 'new', |
| turnstile: true |
| }) |
|
|
| try { |
| const page = isGhost ? |
| await ctx.newPage() : |
| ctx.page |
| await page.goto( |
| url, |
| { waitUntil: 'networkidle0'} |
| ) |
|
|
| const name = format( |
| '%s/%s.png', |
| tmpDir, |
| Math.random().toString(36).slice(2) |
| ) |
|
|
| if (/^\d$/.test(delay) && delay > 0) |
| await setTimeout(+delay) |
| await page.screenshot({ |
| fullPage: full, |
| path: name, |
| omitBackground: transparent |
| }) |
|
|
| res.redirect(name) |
| } catch (e) { |
| console.error(e) |
| res |
| .status(500) |
| .json({ |
| err: true, |
| msg: format(e?.message || e) |
| }) |
| } finally { |
| await (isGhost ? ctx : ctx.browser).close() |
| } |
| }) |
|
|
| const PORT = env.SERVER_PORT || env.PORT || 7860 |
| app.listen( |
| PORT, |
| () => console.log('App running on port', PORT) |
| ) |