read-browser-cookies
Version:
Node.js version of `--cookies-from-browser` from yt-dlp
70 lines (69 loc) • 3.11 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decrypt = exports.getCipherKey = exports.getPassword = exports.getPasswordByKeytar = exports.getPasswordByExternalProcess = void 0;
const crypto_1 = __importDefault(require("crypto"));
const execa_1 = __importDefault(require("execa"));
const keytar_1 = __importDefault(require("keytar"));
function getPasswordByExternalProcess(keyringName) {
const { stdout: password } = execa_1.default.commandSync(`security find-generic-password -w -a '${keyringName}' -s '${keyringName} Safe Storage'`, { shell: true });
return password;
}
exports.getPasswordByExternalProcess = getPasswordByExternalProcess;
async function getPasswordByKeytar(keyringName) {
return (await keytar_1.default.getPassword(`${keyringName} Safe Storage`, keyringName)) || '';
}
exports.getPasswordByKeytar = getPasswordByKeytar;
function getPassword(keyringName) {
return getPasswordByKeytar(keyringName);
}
exports.getPassword = getPassword;
function getCipherKey(password) {
return crypto_1.default.pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1');
}
exports.getCipherKey = getCipherKey;
function decrypt(cipherKey, encryptedValue) {
// version = encrypted_value[:3]
// ciphertext = encrypted_value[3:]
// if version == b'v10':
// self._cookie_counts['v10'] += 1
// if self._v10_key is None:
// self._logger.warning('cannot decrypt v10 cookies: no key found', only_once=True)
// return None
// return _decrypt_aes_cbc(ciphertext, self._v10_key, self._logger)
// else:
// self._cookie_counts['other'] += 1
// # other prefixes are considered 'old data' which were stored as plaintext
// # https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/os_crypt_mac.mm
// return encrypted_value
const version = encryptedValue.subarray(0, 3);
const encryptedPart = encryptedValue.subarray(3);
if (version.toString('ascii') === 'v10') {
return decryptAesCbc(cipherKey, encryptedPart);
}
else {
return encryptedValue.toString();
}
}
exports.decrypt = decrypt;
function decryptAesCbc(cipherKey, encrypted) {
// https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html
// The secret key to use in the symmetric cipher.
// It must be 16, 24 or 32 bytes long (respectively for AES-128, AES-192 or AES-256).
let aesLen = 128;
if (cipherKey.byteLength === 16)
aesLen = 128;
if (cipherKey.byteLength === 24)
aesLen = 192;
if (cipherKey.byteLength === 32)
aesLen = 256;
const alg = `AES-${aesLen}-CBC`;
const iv = Buffer.alloc(16, ' ');
const decipher = crypto_1.default.createDecipheriv(alg, cipherKey, iv);
decipher.setAutoPadding(true);
const bufs = [decipher.update(encrypted), decipher.final()];
const result = Buffer.concat(bufs);
return result.toString();
}