From 9b9c31674df4a7ae14da63fe0832cca12ef97937 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sun, 13 Aug 2023 13:57:34 +0100 Subject: [PATCH] Adds support for client-side cookie identification --- api/cookies.js | 55 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/api/cookies.js b/api/cookies.js index f24d68a..3832195 100644 --- a/api/cookies.js +++ b/api/cookies.js @@ -1,14 +1,57 @@ const axios = require('axios'); +const puppeteer = require('puppeteer'); const middleware = require('./_common/middleware'); -const handler = async (url, event, context) => { +const getPuppeteerCookies = async (url) => { + const browser = await puppeteer.launch({ + headless: 'new', + args: ['--no-sandbox', '--disable-setuid-sandbox'], + }); + try { - const response = await axios.get(url, {withCredentials: true}); - const cookies = response.headers['set-cookie']; - return { cookies }; - } catch (error) { - throw new Error(error.message); + const page = await browser.newPage(); + const navigationPromise = page.goto(url, { waitUntil: 'networkidle2' }); + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Puppeteer took too long!')), 3000) + ); + await Promise.race([navigationPromise, timeoutPromise]); + return await page.cookies(); + } finally { + await browser.close(); } }; +const handler = async (url) => { + let headerCookies = null; + let clientCookies = null; + + try { + const response = await axios.get(url, { + withCredentials: true, + maxRedirects: 5, + }); + headerCookies = response.headers['set-cookie']; + } catch (error) { + if (error.response) { + return { error: `Request failed with status ${error.response.status}: ${error.message}` }; + } else if (error.request) { + return { error: `No response received: ${error.message}` }; + } else { + return { error: `Error setting up request: ${error.message}` }; + } + } + + try { + clientCookies = await getPuppeteerCookies(url); + } catch (_) { + clientCookies = null; + } + + if (!headerCookies && (!clientCookies || clientCookies.length === 0)) { + return { skipped: 'No cookies' }; + } + + return { headerCookies, clientCookies }; +}; + exports.handler = middleware(handler);