@mherod/get-cookie 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +105 -95
- package/package.json +3 -4
package/index.js
CHANGED
|
@@ -53,44 +53,21 @@ async function getFirefoxCookie({name, domain}) {
|
|
|
53
53
|
if (process.env.VERBOSE) {
|
|
54
54
|
console.log(`Trying Firefox cookie ${name} for domain ${domain}`);
|
|
55
55
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sql += `name = '${name}'`;
|
|
63
|
-
if (typeof domain === 'string') {
|
|
64
|
-
sql += ` AND `;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
56
|
+
let sql;
|
|
57
|
+
sql = "SELECT value FROM moz_cookies";
|
|
58
|
+
if (typeof name === 'string' || typeof domain === 'string') {
|
|
59
|
+
sql += ` WHERE `;
|
|
60
|
+
if (typeof name === 'string') {
|
|
61
|
+
sql += `name = '${name}'`;
|
|
67
62
|
if (typeof domain === 'string') {
|
|
68
|
-
sql += `
|
|
63
|
+
sql += ` AND `;
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
console.log(command);
|
|
66
|
+
if (typeof domain === 'string') {
|
|
67
|
+
sql += `host LIKE '${domain}';`;
|
|
74
68
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
reject(error);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
if (stderr) {
|
|
81
|
-
reject(error);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
let stdoutAsBuffer = stdout;
|
|
85
|
-
if (typeof stdoutAsBuffer === 'string' && stdoutAsBuffer.length > 0) {
|
|
86
|
-
// noinspection JSCheckFunctionSignatures
|
|
87
|
-
stdoutAsBuffer = Buffer.from(stdoutAsBuffer, 'binary').slice(0, -1);
|
|
88
|
-
}
|
|
89
|
-
if (stdoutAsBuffer && stdoutAsBuffer.length > 0) {
|
|
90
|
-
resolve(stdoutAsBuffer);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
});
|
|
69
|
+
}
|
|
70
|
+
return await doSqliteQuery1(file, sql);
|
|
94
71
|
}
|
|
95
72
|
|
|
96
73
|
async function getEncryptedChromeCookie(name, domain) {
|
|
@@ -100,33 +77,61 @@ async function getEncryptedChromeCookie(name, domain) {
|
|
|
100
77
|
if (domain && typeof domain !== 'string') {
|
|
101
78
|
throw new Error('domain must be a string');
|
|
102
79
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
sql
|
|
114
|
-
if (typeof name === 'string'
|
|
115
|
-
sql += `
|
|
116
|
-
if (typeof name === 'string') {
|
|
117
|
-
sql += `name = '${name}'`;
|
|
118
|
-
if (typeof domain === 'string') {
|
|
119
|
-
sql += ` AND `;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
80
|
+
const file = `${process.env.HOME}/Library/Application Support/Google/Chrome/Default/Cookies`;
|
|
81
|
+
if (!fs.existsSync(file)) {
|
|
82
|
+
throw new Error(`File ${file} does not exist`);
|
|
83
|
+
}
|
|
84
|
+
if (process.env.VERBOSE) {
|
|
85
|
+
console.log(`Trying Chrome cookie ${name} for domain ${domain}`);
|
|
86
|
+
}
|
|
87
|
+
let sql;
|
|
88
|
+
sql = `SELECT encrypted_value FROM cookies`;
|
|
89
|
+
if (typeof name === 'string' || typeof domain === 'string') {
|
|
90
|
+
sql += ` WHERE `;
|
|
91
|
+
if (typeof name === 'string') {
|
|
92
|
+
sql += `name = '${name}'`;
|
|
122
93
|
if (typeof domain === 'string') {
|
|
123
|
-
sql += `
|
|
94
|
+
sql += ` AND `;
|
|
124
95
|
}
|
|
125
96
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
console.log(command);
|
|
97
|
+
if (typeof domain === 'string') {
|
|
98
|
+
sql += `host_key LIKE '${domain}';`;
|
|
129
99
|
}
|
|
100
|
+
}
|
|
101
|
+
return await doSqliteQuery1(file, sql);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function doSqliteQuery1(file, sql) {
|
|
105
|
+
const sqlite3 = require('sqlite3');
|
|
106
|
+
const db = new sqlite3.Database(file);
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
db.all(sql, (err, rows) => {
|
|
109
|
+
if (err) {
|
|
110
|
+
reject(err);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const rows1 = rows;
|
|
114
|
+
if (rows1.length === 0) {
|
|
115
|
+
resolve(null);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (Array.isArray(rows1)) {
|
|
119
|
+
// noinspection JSCheckFunctionSignatures
|
|
120
|
+
const [value] = rows1.flatMap(row => Object.values(row));
|
|
121
|
+
resolve(value);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
resolve(rows1);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function doSqliteQuery(file, sql) {
|
|
130
|
+
const command = `sqlite3 "${file}" "${sql}"`;
|
|
131
|
+
if (process.env.VERBOSE) {
|
|
132
|
+
console.log(command);
|
|
133
|
+
}
|
|
134
|
+
return await new Promise((resolve, reject) => {
|
|
130
135
|
exec(command, {encoding: 'binary', maxBuffer: 5 * 1024}, (error, stdout, stderr) => {
|
|
131
136
|
if (error) {
|
|
132
137
|
reject(error);
|
|
@@ -166,53 +171,58 @@ async function decrypt(password, encryptedData) {
|
|
|
166
171
|
}
|
|
167
172
|
return await new Promise((resolve, reject) => {
|
|
168
173
|
crypto.pbkdf2(password, 'saltysalt', 1003, 16, 'sha1', (error, buffer) => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
try {
|
|
175
|
+
|
|
176
|
+
if (error) {
|
|
177
|
+
if (process.env.VERBOSE) {
|
|
178
|
+
console.log("Error doing pbkdf2", error);
|
|
179
|
+
}
|
|
180
|
+
reject(error);
|
|
181
|
+
return;
|
|
172
182
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
if (buffer.length !== 16) {
|
|
184
|
+
if (process.env.VERBOSE) {
|
|
185
|
+
console.log("Error doing pbkdf2, buffer length is not 16", buffer.length);
|
|
186
|
+
}
|
|
187
|
+
reject(new Error('Buffer length is not 16'));
|
|
188
|
+
return;
|
|
179
189
|
}
|
|
180
|
-
reject(new Error('Buffer length is not 16'));
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
const iv = new Buffer.from(new Array(17).join(' '), 'binary');
|
|
192
|
+
const decipher = crypto.createDecipheriv('aes-128-cbc', buffer, iv);
|
|
193
|
+
decipher.setAutoPadding(false);
|
|
194
|
+
encryptedData = encryptedData.slice(3);
|
|
188
195
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
196
|
+
if (encryptedData.length % 16 !== 0) {
|
|
197
|
+
if (process.env.VERBOSE) {
|
|
198
|
+
console.log("Error doing pbkdf2, encryptedData length is not a multiple of 16", encryptedData.length);
|
|
199
|
+
}
|
|
200
|
+
reject(new Error('encryptedData length is not a multiple of 16'));
|
|
201
|
+
return;
|
|
192
202
|
}
|
|
193
|
-
reject(new Error('encryptedData length is not a multiple of 16'));
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
203
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
let decoded = decipher.update(encryptedData, 'binary', 'utf8');
|
|
205
|
+
// let decoded = decipher.update(encryptedData);
|
|
206
|
+
try {
|
|
207
|
+
decipher.final('utf-8');
|
|
208
|
+
} catch (e) {
|
|
209
|
+
if (process.env.VERBOSE) {
|
|
210
|
+
console.log("Error doing decipher.final()", e);
|
|
211
|
+
}
|
|
212
|
+
reject(e);
|
|
213
|
+
return;
|
|
204
214
|
}
|
|
205
|
-
reject(e);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
215
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
let padding = decoded[decoded.length - 1];
|
|
217
|
+
if (padding) {
|
|
218
|
+
decoded = decoded.slice(0, 0 - padding);
|
|
219
|
+
}
|
|
220
|
+
// noinspection JSCheckFunctionSignatures
|
|
221
|
+
decoded = decoded.toString('utf8');
|
|
222
|
+
resolve(decoded);
|
|
223
|
+
} catch (e) {
|
|
224
|
+
reject(e);
|
|
212
225
|
}
|
|
213
|
-
// noinspection JSCheckFunctionSignatures
|
|
214
|
-
decoded = decoded.toString('utf8');
|
|
215
|
-
resolve(decoded)
|
|
216
226
|
});
|
|
217
227
|
});
|
|
218
228
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mherod/get-cookie",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Node.js module for querying a local user's Chrome cookie",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": "index.js",
|
|
@@ -9,13 +9,12 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
|
-
"
|
|
13
|
-
"installForMac": "pkg . --target node17-macos-x64 --out-path /usr/local/bin/ --debug",
|
|
14
|
-
"installForHost": "pkg . --target host --out-path /usr/local/bin/ --debug"
|
|
12
|
+
"install": "npm install --force --global ."
|
|
15
13
|
},
|
|
16
14
|
"keywords": [],
|
|
17
15
|
"author": "Matthew Herod",
|
|
18
16
|
"license": "ISC",
|
|
19
17
|
"dependencies": {
|
|
18
|
+
"sqlite3": "^5.0.8"
|
|
20
19
|
}
|
|
21
20
|
}
|