puppeteer-tough-cookie-store
Version:
Puppeteer cookie store implementation for tough-cookie
176 lines (153 loc) • 5.28 kB
text/typescript
import type { Cookie, Store } from 'tough-cookie'
import type { CDPSession, Protocol } from 'puppeteer'
import { fromPromise } from 'universalify'
import { serializeForTough, serializeForPuppeteer } from './utils'
/**
* Options for `PuppeteerToughCookieStore`
*/
export interface StoreOptions {
/**
* Changed getAllCookies behavior
*/
getAllCookiesUrls?: string[],
/**
* Fix `Cannot delete property 'creationIndex' of [object Object]` inside tough-cookie package
*
* [closed issue #1](https://github.com/salesforce/tough-cookie/issues/192) |
* [issue #2](https://github.com/salesforce/tough-cookie/issues/199)
*
* `getAllCookies` will call `.toJSON` before return cookies
*
* BE CAREFUL: TYPES WILL LIE TO YOU
*
* @deprecated
*/
_getAllCookies_returnPlainObject?: boolean,
}
/**
* @class PuppeteerToughCookieStore
*/
export class PuppeteerToughCookieStore implements Store {
/**
* Current store driver works async only
*/
public synchronous = false;
constructor(
/** @internal */
public client: CDPSession,
/** @internal */
public options: StoreOptions = {}) {
}
/**
* Returns browser cookies for the specific domain and path in puppeteer's format
*
* @internal
*/
async findCdpCookies(domain: string, path?: string, allowSpecialUseDomain?: boolean):
Promise<Protocol.Network.Cookie[]> {
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: string, path: string, key: string): Promise<Cookie | undefined> {
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: string, path?: string, allowSpecialUseDomain?: boolean):
Promise<Cookie[]> {
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: Cookie): Promise<void> {
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: Cookie[]): Promise<void> {
await this.client.send("Network.setCookies", {
cookies: cookies.map(serializeForPuppeteer)
})
};
/**
* Updates a cookie; in reality almost an alias for `.putCookies`
*/
async updateCookie(oldCookie: Cookie, newCookie: Cookie): Promise<void> {
// puppeteer will manage its own
await this.putCookie(newCookie);
};
/**
* Deletes browser cookies with matching name, domain and path.
*/
async removeCookie(domain: string, path: string, key: string): Promise<void> {
await this.client.send("Network.deleteCookies", {
name: key,
domain,
path,
})
};
/**
* Deletes browser cookies with matching domain and path.
*/
async removeCookies(domain: string, path: string): Promise<void> {
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(): Promise<Cookie[]> {
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(): Promise<void> {
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]
)
})