File size: 1,878 Bytes
5bab120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import Cookie from './cookie.js';
import { readFile, writeFile } from 'fs/promises';
import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser';
import { env } from '../../config.js';

const WRITE_INTERVAL = 60000,
      cookiePath = env.cookiePath,
      COUNTER = Symbol('counter');

let cookies = {}, dirty = false, intervalId;

const setup = async () => {
    try {
        if (!cookiePath) return;

        cookies = await readFile(cookiePath, 'utf8');
        cookies = JSON.parse(cookies);
        intervalId = setInterval(writeChanges, WRITE_INTERVAL)
    } catch { /* no cookies for you */ }
}

setup();

function writeChanges() {
    if (!dirty) return;
    dirty = false;

    writeFile(cookiePath, JSON.stringify(cookies, null, 4)).catch(() => {
        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]
}

export function updateCookie(cookie, headers) {
    if (!cookie) return;

    const parsed = parseSetCookie(
        splitCookiesString(headers.get('set-cookie')),
        { decodeValues: false }
    ), values = {}

    cookie.unset(parsed.filter(c => c.expires < new Date()).map(c => c.name));
    parsed.filter(c => !c.expires || c.expires > new Date()).forEach(c => values[c.name] = c.value);
    updateCookieValues(cookie, values);
}

export function updateCookieValues(cookie, values) {
    cookie.set(values);
    if (Object.keys(values).length) dirty = true
}