mirror of
https://github.com/imputnet/cobalt.git
synced 2026-01-07 23:41:39 +00:00
add cookie support
usage:
- create cookies.json file somewhere, preferrably outside cobalt directory
- in docker, you can bind mount it (`volumes` in composefile)
- if you don't want cobalt to update the cookies, set it to `:ro` (cobalt will print a warning about this, ignore it)
- set COOKIE_PATH to the absolute path of this file
- enjoy?
usage in services: probably the simplest api ever
- import { getCookie, updateCookie } from '../../cookie/manager.js';
- const cookie = getCookie('<service_name>');
- add this to headers - `headers: { cookie }`
- after fetch is done, save potential cookie updates: updateCookie(cookie, fetch.headers)
- see instagram.js for example usage
This commit is contained in:
78
src/modules/cookie/manager.js
Normal file
78
src/modules/cookie/manager.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import path from 'path'
|
||||
import Cookie from './cookie.js'
|
||||
import { readFile, writeFile } from 'fs/promises'
|
||||
import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser'
|
||||
|
||||
const WRITE_INTERVAL = 60000,
|
||||
COOKIE_PATH = process.env.COOKIE_PATH,
|
||||
COUNTER = Symbol('counter');
|
||||
|
||||
let cookies = {}, dirty = false, intervalId;
|
||||
|
||||
const setup = async () => {
|
||||
try {
|
||||
if (!COOKIE_PATH)
|
||||
return
|
||||
|
||||
cookies = await readFile(COOKIE_PATH, 'utf8')
|
||||
cookies = JSON.parse(cookies)
|
||||
intervalId = setInterval(writeChanges, WRITE_INTERVAL)
|
||||
} catch { /* no cookies for you */ }
|
||||
}
|
||||
|
||||
setup()
|
||||
|
||||
function writeChanges() {
|
||||
if (!dirty) return
|
||||
dirty = false
|
||||
|
||||
writeFile(
|
||||
COOKIE_PATH,
|
||||
JSON.stringify(cookies, null, 4)
|
||||
).catch(e => {
|
||||
console.error('warn: cookies failed to save, stopping interval')
|
||||
console.error('exception:', e)
|
||||
clearInterval(intervalId)
|
||||
})
|
||||
}
|
||||
|
||||
export function getCookie(service) {
|
||||
if (!cookies[service] || !cookies[service].length)
|
||||
return
|
||||
|
||||
let n
|
||||
if (cookies[service][COUNTER] === undefined) {
|
||||
n = cookies[service][COUNTER] = 0
|
||||
} else {
|
||||
++cookies[service][COUNTER]
|
||||
n = (cookies[service][COUNTER] %= cookies[service].length)
|
||||
}
|
||||
|
||||
const cookie = cookies[service][n]
|
||||
if (typeof cookie === 'string')
|
||||
cookies[service][n] = Cookie.fromString(cookie)
|
||||
|
||||
return cookies[service][n]
|
||||
}
|
||||
|
||||
// todo: expiry checking? domain checking?
|
||||
// might be pointless for the purposes of cobalt
|
||||
export function updateCookie(cookie, headers) {
|
||||
const parsed = parseSetCookie(
|
||||
splitCookiesString(headers.get('set-cookie'))
|
||||
), values = {}
|
||||
|
||||
cookie.unset(
|
||||
parsed
|
||||
.filter(c => c.expires < new Date())
|
||||
.map(c => c.name)
|
||||
)
|
||||
|
||||
parsed
|
||||
.filter(c => c.expires > new Date())
|
||||
.forEach(c => values[c.name] = c.value);
|
||||
|
||||
cookie.set(values)
|
||||
if (Object.keys(values).length)
|
||||
dirty = true
|
||||
}
|
||||
Reference in New Issue
Block a user