UNPKG

puppeteer-tough-cookie-store

Version:

Puppeteer cookie store implementation for tough-cookie

244 lines (238 loc) 7.53 kB
/*! * puppeteer-tough-cookie-store v1.2.0 by Utyfua * https://github.com/utyfua/puppeteer-tough-cookie-store * @license MIT */ import { fromPromise } from 'universalify'; import { Cookie, canonicalDomain } from 'tough-cookie'; const PuppeteerInfinityExpires = -1; const ToughInfinityExpires = "Infinity"; /** * convert puppeteer's sameSite to tough-cookie's sameSite */ const p2tSameSite = (sameSite) => { switch (sameSite) { case 'Lax': return 'lax'; case 'Strict': return 'strict'; case 'None': default: return 'none'; } }; /** * convert tough-cookie's sameSite to puppeteer's sameSite */ const t2pSameSite = (sameSite) => { sameSite = sameSite ? sameSite.toLocaleLowerCase() : 'none'; switch (sameSite) { case 'lax': return 'Lax'; case 'strict': return 'Strict'; case 'none': default: return 'Lax'; } }; /** * convert puppeteer's cookie to tough-cookie's cookie */ const serializeForTough = (puppetCookie) => { const toughCookie = new Cookie({ key: puppetCookie.name, value: puppetCookie.value, expires: (!puppetCookie.expires || puppetCookie.expires === PuppeteerInfinityExpires) ? ToughInfinityExpires : new Date(puppetCookie.expires * 1000), domain: canonicalDomain(puppetCookie.domain), path: puppetCookie.path, secure: puppetCookie.secure, httpOnly: puppetCookie.httpOnly, sameSite: p2tSameSite(puppetCookie.sameSite), hostOnly: !puppetCookie.domain.startsWith("."), // can we really skip them? // creation: currentDate, // lastAccessed: currentDate, }); return toughCookie; }; /** * convert tough-cookie's cookie to puppeteer's cookie */ const serializeForPuppeteer = (toughCookie) => { if (!toughCookie.domain) throw new Error("Unknown domain"); const puppetCookie = { name: toughCookie.key, value: toughCookie.value, // domain: !cookie.hostOnly ? '.' + cookie.domain : cookie.domain, domain: toughCookie.domain, path: toughCookie.path || '/', expires: !toughCookie.expires || toughCookie.expires === ToughInfinityExpires ? PuppeteerInfinityExpires : toughCookie.expires.getTime(), secure: toughCookie.secure, httpOnly: toughCookie.hostOnly === null ? undefined : toughCookie.hostOnly, sameSite: t2pSameSite(toughCookie.sameSite), }; return puppetCookie; }; var utils = /*#__PURE__*/Object.freeze({ __proto__: null, PuppeteerInfinityExpires: PuppeteerInfinityExpires, ToughInfinityExpires: ToughInfinityExpires, p2tSameSite: p2tSameSite, serializeForPuppeteer: serializeForPuppeteer, serializeForTough: serializeForTough, t2pSameSite: t2pSameSite }); /** * @class PuppeteerToughCookieStore */ class PuppeteerToughCookieStore { constructor( /** @internal */ client, /** @internal */ options = {}) { this.client = client; this.options = options; /** * Current store driver works async only */ this.synchronous = false; } /** * Returns browser cookies for the specific domain and path in puppeteer's format * * @internal */ async findCdpCookies(domain, path, allowSpecialUseDomain) { const { cookies } = await this.client.send("Network.getCookies", { urls: ['https://' + domain + (path || '')] }); return cookies.filter(cookie => cookie.name !== ""); } /** * Returns cookie for the specific domain and path */ async findCookie(domain, path, key) { const cookies = await this.findCdpCookies(domain, path); const cookie = cookies.find(({ name }) => name === key); return cookie ? serializeForTough(cookie) : undefined; } ; /** * Returns cookies for the specific domain and path */ async findCookies(domain, path, allowSpecialUseDomain) { const cookies = await this.findCdpCookies(domain, path, allowSpecialUseDomain); return cookies.map(serializeForTough); } ; /** * Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist. */ async putCookie(cookie) { if (cookie.key === '') return; await this.client.send("Network.setCookie", serializeForPuppeteer(cookie)); } ; /** * Sets a cookies with the given cookies; may overwrite equivalent cookies if they exist. */ async putCookies(cookies) { await this.client.send("Network.setCookies", { cookies: cookies.map(serializeForPuppeteer) }); } ; /** * Updates a cookie; in reality almost an alias for `.putCookies` */ async updateCookie(oldCookie, newCookie) { // puppeteer will manage its own await this.putCookie(newCookie); } ; /** * Deletes browser cookies with matching name, domain and path. */ async removeCookie(domain, path, key) { await this.client.send("Network.deleteCookies", { name: key, domain, path, }); } ; /** * Deletes browser cookies with matching domain and path. */ async removeCookies(domain, path) { const cookies = await this.findCdpCookies(domain, path); for (const cookie of cookies) { await this.removeCookie(domain, path, cookie.name); } } ; /** * Returns all browser cookies. Depending on the backend support, will return detailed cookie * information in the `cookies` field. * * If `options.getAllCookiesUrls` set will return cookies only for those specific urls */ async getAllCookies() { const { cookies } = this.options.getAllCookiesUrls ? await this.client.send("Network.getCookies", { urls: this.options.getAllCookiesUrls }) : await this.client.send("Network.getAllCookies"); if (this.options._getAllCookies_returnPlainObject) { // @ts-ignore: i understand that its bad, but user were warned return cookies.map(serializeForTough).map(cookie => cookie.toJSON()); } return cookies.map(serializeForTough); } ; /** * Clears browser cookies. */ async removeAllCookies() { await this.client.send("Network.clearBrowserCookies"); } ; } // todo: fix types [ 'findCookie', 'findCookies', 'getAllCookies', 'putCookie', 'putCookies', 'removeAllCookies', 'removeCookie', 'removeCookies', 'updateCookie' ].forEach(name => { // @ts-ignore PuppeteerToughCookieStore.prototype[name] = fromPromise( // @ts-ignore PuppeteerToughCookieStore.prototype[name]); }); /*/ this didnt work(tested getAllCookies only) export async function getStoreByBrowser(browser: Browser, options?: StoreOptions): Promise<PuppeteerToughCookieStore> { const client = await browser.target().createCDPSession() return new PuppeteerToughCookieStore(client, options) } */ async function getStoreByPage(page, options) { const client = await page.target().createCDPSession(); return new PuppeteerToughCookieStore(client, options); } export { PuppeteerToughCookieStore, getStoreByPage, utils }; //# sourceMappingURL=index.esm.js.map