92 lines
2.9 KiB
JavaScript
92 lines
2.9 KiB
JavaScript
import { execFileSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { profileDirectory } from './config.mjs';
|
|
|
|
const BASE = path.dirname(fileURLToPath(import.meta.url));
|
|
const HELPER = path.join(BASE, 'cookie-protection.ps1');
|
|
const POWERSHELL = path.join(
|
|
process.env.SystemRoot || 'C:\\Windows',
|
|
'System32/WindowsPowerShell/v1.0/powershell.exe',
|
|
);
|
|
const DOMAINS = [
|
|
'.alipay.com',
|
|
'alipay.com',
|
|
'auth.alipay.com',
|
|
'b.alipay.com',
|
|
'authweb.alipay.com',
|
|
'.mybank.cn',
|
|
'mybank.cn',
|
|
'b.mybank.cn',
|
|
'fund.mybank.cn',
|
|
'login.mybank.cn',
|
|
];
|
|
|
|
function cookieFile(account) {
|
|
return path.join(profileDirectory(account), 'auth-cookies.dpapi');
|
|
}
|
|
|
|
function protect(value) {
|
|
return execFileSync(
|
|
POWERSHELL,
|
|
['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', HELPER, '-Action', 'Protect'],
|
|
{ input: Buffer.from(value, 'utf8'), maxBuffer: 32 * 1024 * 1024, windowsHide: true },
|
|
).toString('utf8').trim();
|
|
}
|
|
|
|
function unprotect(value) {
|
|
return execFileSync(
|
|
POWERSHELL,
|
|
['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', HELPER, '-Action', 'Unprotect'],
|
|
{ input: Buffer.from(value, 'utf8'), maxBuffer: 32 * 1024 * 1024, windowsHide: true },
|
|
).toString('utf8').trim();
|
|
}
|
|
|
|
function allowed(cookie) {
|
|
const domain = String(cookie.domain || '').toLowerCase();
|
|
return DOMAINS.some((item) => domain === item || domain.endsWith(item));
|
|
}
|
|
|
|
export async function saveCookies(cdp, account) {
|
|
const payload = await cdp.send('Storage.getCookies');
|
|
const cookies = (payload.cookies || []).filter(allowed);
|
|
if (cookies.length === 0) return false;
|
|
|
|
const file = cookieFile(account);
|
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
const encrypted = protect(Buffer.from(JSON.stringify(cookies), 'utf8').toString('base64'));
|
|
const temporary = file + '.tmp';
|
|
fs.writeFileSync(temporary, encrypted + '\r\n', { encoding: 'utf8', mode: 0o600 });
|
|
fs.renameSync(temporary, file);
|
|
|
|
return true;
|
|
}
|
|
|
|
export async function restoreCookies(cdp, account) {
|
|
const file = cookieFile(account);
|
|
if (!fs.existsSync(file)) return false;
|
|
|
|
try {
|
|
const encrypted = fs.readFileSync(file, 'utf8').trim();
|
|
const json = Buffer.from(unprotect(encrypted), 'base64').toString('utf8');
|
|
const cookies = JSON.parse(json);
|
|
if (!Array.isArray(cookies) || cookies.length === 0) return false;
|
|
|
|
const allowedKeys = [
|
|
'name', 'value', 'domain', 'path', 'expires', 'httpOnly', 'secure',
|
|
'sameSite', 'priority', 'sameParty', 'sourceScheme', 'sourcePort',
|
|
];
|
|
await cdp.send('Storage.setCookies', {
|
|
cookies: cookies.map((cookie) => Object.fromEntries(
|
|
allowedKeys
|
|
.filter((key) => cookie[key] !== undefined)
|
|
.map((key) => [key, cookie[key]]),
|
|
)),
|
|
});
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|