Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aff6300cbd | ||
|
|
2220b92849 |
5
.trivyignore
Normal file
5
.trivyignore
Normal file
@@ -0,0 +1,5 @@
|
||||
# Chrome on Debian 12 currently pulls these runtime libraries without distro fixes available.
|
||||
# Keep these temporary and remove them once Debian or Google Chrome ships patched packages.
|
||||
CVE-2023-45853
|
||||
CVE-2025-7458
|
||||
CVE-2026-40393
|
||||
52
Dockerfile
52
Dockerfile
@@ -1,43 +1,55 @@
|
||||
FROM node:20.12.2-slim
|
||||
FROM node:20.19.5-bookworm-slim AS deps
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
RUN node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); pkg.pnpm = pkg.pnpm || {}; pkg.pnpm.overrides = { ...(pkg.pnpm.overrides || {}), 'basic-ftp': '5.3.0', 'path-to-regexp': '8.4.0', 'qs': '6.14.2' }; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');" \
|
||||
&& corepack enable \
|
||||
&& corepack prepare pnpm@10.33.2 --activate \
|
||||
&& pnpm install --no-frozen-lockfile --prod \
|
||||
&& pnpm store prune
|
||||
|
||||
FROM node:20.19.5-bookworm-slim
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Install Chrome and dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates wget gnupg xvfb fonts-liberation \
|
||||
RUN savedAptMark="$(apt-mark showmanual)" \
|
||||
&& apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
fonts-liberation \
|
||||
gnupg \
|
||||
wget \
|
||||
xvfb \
|
||||
&& wget -qO- https://dl.google.com/linux/linux_signing_key.pub \
|
||||
| gpg --dearmor -o /usr/share/keyrings/google-linux-signing-keyring.gpg \
|
||||
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-linux-signing-keyring.gpg] https://dl.google.com/linux/chrome/deb/ stable main" \
|
||||
> /etc/apt/sources.list.d/google-chrome.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends google-chrome-stable \
|
||||
&& apt-get purge -y --auto-remove wget gnupg \
|
||||
&& [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark \
|
||||
&& apt-mark manual ca-certificates fonts-liberation google-chrome-stable xvfb \
|
||||
&& rm -f /etc/apt/sources.list.d/google-chrome.list /usr/share/keyrings/google-linux-signing-keyring.gpg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
# Create a non-root user for running the app
|
||||
RUN useradd --create-home --home-dir /app --shell /bin/sh appuser
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Entrypoint script
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Copy and install dependencies
|
||||
COPY --chown=appuser:appuser package.json pnpm-lock.yaml ./
|
||||
USER appuser
|
||||
RUN corepack prepare pnpm@9.0.0 --activate \
|
||||
&& pnpm install --frozen-lockfile --prod \
|
||||
&& pnpm store prune
|
||||
|
||||
# Copy app code
|
||||
COPY --from=deps --chown=appuser:appuser /app/node_modules ./node_modules
|
||||
COPY --chown=appuser:appuser package.json ./
|
||||
COPY --chown=appuser:appuser . .
|
||||
|
||||
# Expose port (match your app's port)
|
||||
RUN rm -rf /usr/local/lib/node_modules/npm \
|
||||
&& rm -f /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 10000
|
||||
|
||||
# Start Xvfb and run the bot
|
||||
CMD ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
|
||||
15
README.md
15
README.md
@@ -119,13 +119,15 @@ Open a page and wait for a specific cookie to appear.
|
||||
```json
|
||||
{
|
||||
"domain": "https://example.com/",
|
||||
"cookieName": "session_id"
|
||||
"cookieName": "session_id",
|
||||
"includeCookies": true
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
- **`domain`** (required): Target website URL
|
||||
- **`cookieName`** (required): Cookie name to wait for
|
||||
- **`includeCookies`** (optional): Include the full browser cookie jar in the response
|
||||
- **`user_agent`** (optional): User-Agent to use for the browser session
|
||||
- **`proxy`** (optional): Proxy configuration object
|
||||
|
||||
@@ -138,6 +140,16 @@ Open a page and wait for a specific cookie to appear.
|
||||
"cookie_path": "/",
|
||||
"http_only": true,
|
||||
"secure": true,
|
||||
"cookies": [
|
||||
{
|
||||
"name": "session_id",
|
||||
"value": "abc123",
|
||||
"domain": ".example.com",
|
||||
"path": "/",
|
||||
"httpOnly": true,
|
||||
"secure": true
|
||||
}
|
||||
],
|
||||
"user_agent": "Mozilla/5.0...",
|
||||
"elapsed_time": 1.42
|
||||
}
|
||||
@@ -148,6 +160,7 @@ Open a page and wait for a specific cookie to appear.
|
||||
{
|
||||
"cookie_name": "session_id",
|
||||
"cookie_value": null,
|
||||
"cookies": [],
|
||||
"user_agent": "Mozilla/5.0...",
|
||||
"elapsed_time": 60.0
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ async def main():
|
||||
json={
|
||||
"domain": "https://example.com/",
|
||||
"cookieName": "session_id",
|
||||
"includeCookies": True,
|
||||
},
|
||||
)
|
||||
print(resp3.json())
|
||||
|
||||
@@ -6,7 +6,7 @@ xvfb_pid=$!
|
||||
|
||||
export DISPLAY=:99
|
||||
|
||||
npm start &
|
||||
node index.js &
|
||||
app_pid=$!
|
||||
|
||||
term_handler() {
|
||||
|
||||
@@ -8,7 +8,29 @@ function logBrowserCookies({ domain, cookieName, cookies }) {
|
||||
)
|
||||
}
|
||||
|
||||
async function waitForCookie({ domain, proxy, cookieName }, page) {
|
||||
function buildCookieResponse({ cookieName, matchedCookie, userAgent, elapsedTime, cookies, includeCookies }) {
|
||||
const result = {
|
||||
cookie_name: matchedCookie?.name ?? cookieName,
|
||||
cookie_value: matchedCookie?.value ?? null,
|
||||
user_agent: userAgent,
|
||||
elapsed_time: elapsedTime,
|
||||
}
|
||||
|
||||
if (matchedCookie) {
|
||||
result.cookie_domain = matchedCookie.domain
|
||||
result.cookie_path = matchedCookie.path
|
||||
result.http_only = matchedCookie.httpOnly
|
||||
result.secure = matchedCookie.secure
|
||||
}
|
||||
|
||||
if (includeCookies) {
|
||||
result.cookies = cookies
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async function waitForCookie({ domain, proxy, cookieName, includeCookies }, page) {
|
||||
if (!domain) throw new Error("Missing domain parameter")
|
||||
if (!cookieName) throw new Error("Missing cookieName parameter")
|
||||
|
||||
@@ -33,16 +55,14 @@ async function waitForCookie({ domain, proxy, cookieName }, page) {
|
||||
|
||||
if (match) {
|
||||
logBrowserCookies({ domain, cookieName, cookies })
|
||||
return {
|
||||
cookie_name: match.name,
|
||||
cookie_value: match.value,
|
||||
cookie_domain: match.domain,
|
||||
cookie_path: match.path,
|
||||
http_only: match.httpOnly,
|
||||
secure: match.secure,
|
||||
user_agent: userAgent,
|
||||
elapsed_time: (Date.now() - startTime) / 1000,
|
||||
}
|
||||
return buildCookieResponse({
|
||||
cookieName,
|
||||
matchedCookie: match,
|
||||
userAgent,
|
||||
elapsedTime: (Date.now() - startTime) / 1000,
|
||||
cookies,
|
||||
includeCookies,
|
||||
})
|
||||
}
|
||||
|
||||
await sleep(pollInterval)
|
||||
@@ -51,12 +71,13 @@ async function waitForCookie({ domain, proxy, cookieName }, page) {
|
||||
const cookies = await page.cookies()
|
||||
logBrowserCookies({ domain, cookieName, cookies })
|
||||
|
||||
return {
|
||||
cookie_name: cookieName,
|
||||
cookie_value: null,
|
||||
user_agent: userAgent,
|
||||
elapsed_time: (Date.now() - startTime) / 1000,
|
||||
}
|
||||
return buildCookieResponse({
|
||||
cookieName,
|
||||
userAgent,
|
||||
elapsedTime: (Date.now() - startTime) / 1000,
|
||||
cookies,
|
||||
includeCookies,
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = waitForCookie
|
||||
|
||||
3
index.js
3
index.js
@@ -173,6 +173,9 @@ app.post('/cookie', async (req, res) => {
|
||||
if (!data || typeof data.domain !== 'string' || typeof data.cookieName !== 'string') {
|
||||
return res.status(400).json({ message: 'Bad Request: missing or invalid domain/cookieName' })
|
||||
}
|
||||
if (typeof data.includeCookies !== 'undefined' && typeof data.includeCookies !== 'boolean') {
|
||||
return res.status(400).json({ message: 'Bad Request: invalid includeCookies' })
|
||||
}
|
||||
if (data.user_agent && typeof data.user_agent !== 'string') {
|
||||
return res.status(400).json({ message: 'Bad Request: invalid user_agent' })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user