@dongdev/fca-unofficial 3.0.15 → 3.0.19

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/CHANGELOG.md CHANGED
@@ -167,3 +167,9 @@ Too lazy to write changelog, sorry! (will write changelog in the next release, t
167
167
 
168
168
  ## v3.0.12 - 2025-12-05
169
169
  - Hotfix / auto bump
170
+
171
+ ## v3.0.15 - 2025-12-12
172
+ - Hotfix / auto bump
173
+
174
+ ## v3.0.17 - 2025-12-16
175
+ - Hotfix / auto bump
@@ -289,26 +289,101 @@ async function setJarCookies(j, appstate) {
289
289
  const cookiePath = c.path || "/";
290
290
  const dom = cookieDomain.replace(/^\./, "");
291
291
 
292
- // Format expires if provided
292
+ // Handle expirationDate (can be in seconds or milliseconds)
293
293
  let expiresStr = "";
294
- if (c.expires) {
294
+ if (c.expirationDate !== undefined) {
295
+ let expiresDate;
296
+ if (typeof c.expirationDate === "number") {
297
+ // If expirationDate is less than a year from now in seconds, treat as seconds
298
+ // Otherwise treat as milliseconds
299
+ const now = Date.now();
300
+ const oneYearInMs = 365 * 24 * 60 * 60 * 1000;
301
+ if (c.expirationDate < (now + oneYearInMs) / 1000) {
302
+ expiresDate = new Date(c.expirationDate * 1000);
303
+ } else {
304
+ expiresDate = new Date(c.expirationDate);
305
+ }
306
+ } else {
307
+ expiresDate = new Date(c.expirationDate);
308
+ }
309
+ expiresStr = `; expires=${expiresDate.toUTCString()}`;
310
+ } else if (c.expires) {
295
311
  const expiresDate = typeof c.expires === "number" ? new Date(c.expires) : new Date(c.expires);
296
312
  expiresStr = `; expires=${expiresDate.toUTCString()}`;
297
313
  }
298
314
 
299
- // Build cookie string
300
- const str = `${cookieName}=${cookieValue}${expiresStr}; Domain=${cookieDomain}; Path=${cookiePath};`;
315
+ // Helper function to build cookie string
316
+ const buildCookieString = (domainOverride = null) => {
317
+ const domain = domainOverride || cookieDomain;
318
+ let cookieParts = [`${cookieName}=${cookieValue}${expiresStr}`];
319
+ cookieParts.push(`Domain=${domain}`);
320
+ cookieParts.push(`Path=${cookiePath}`);
321
+
322
+ // Add Secure flag if secure is true
323
+ if (c.secure === true) {
324
+ cookieParts.push("Secure");
325
+ }
326
+
327
+ // Add HttpOnly flag if httpOnly is true
328
+ if (c.httpOnly === true) {
329
+ cookieParts.push("HttpOnly");
330
+ }
331
+
332
+ // Add SameSite attribute if provided
333
+ if (c.sameSite) {
334
+ const sameSiteValue = String(c.sameSite).toLowerCase();
335
+ if (["strict", "lax", "none"].includes(sameSiteValue)) {
336
+ cookieParts.push(`SameSite=${sameSiteValue.charAt(0).toUpperCase() + sameSiteValue.slice(1)}`);
337
+ }
338
+ }
339
+
340
+ return cookieParts.join("; ");
341
+ };
301
342
 
302
- // Set cookie for both http and https, with and without www
303
- const base1 = `http://${dom}${cookiePath}`;
304
- const base2 = `https://${dom}${cookiePath}`;
305
- const base3 = `http://www.${dom}${cookiePath}`;
306
- const base4 = `https://www.${dom}${cookiePath}`;
343
+ // Determine target URLs and cookie strings based on domain
344
+ const cookieConfigs = [];
345
+
346
+ // For .facebook.com domain, set for both facebook.com and messenger.com
347
+ if (cookieDomain === ".facebook.com" || cookieDomain === "facebook.com") {
348
+ // Set for facebook.com with .facebook.com domain
349
+ cookieConfigs.push({ url: `http://${dom}${cookiePath}`, cookieStr: buildCookieString() });
350
+ cookieConfigs.push({ url: `https://${dom}${cookiePath}`, cookieStr: buildCookieString() });
351
+ cookieConfigs.push({ url: `http://www.${dom}${cookiePath}`, cookieStr: buildCookieString() });
352
+ cookieConfigs.push({ url: `https://www.${dom}${cookiePath}`, cookieStr: buildCookieString() });
353
+
354
+ // Set for messenger.com with .messenger.com domain (or without domain for host-only)
355
+ // Use .messenger.com domain to allow cross-subdomain sharing
356
+ cookieConfigs.push({ url: `http://messenger.com${cookiePath}`, cookieStr: buildCookieString(".messenger.com") });
357
+ cookieConfigs.push({ url: `https://messenger.com${cookiePath}`, cookieStr: buildCookieString(".messenger.com") });
358
+ cookieConfigs.push({ url: `http://www.messenger.com${cookiePath}`, cookieStr: buildCookieString(".messenger.com") });
359
+ cookieConfigs.push({ url: `https://www.messenger.com${cookiePath}`, cookieStr: buildCookieString(".messenger.com") });
360
+ } else if (cookieDomain === ".messenger.com" || cookieDomain === "messenger.com") {
361
+ // Set for messenger.com only
362
+ const messengerDom = cookieDomain.replace(/^\./, "");
363
+ cookieConfigs.push({ url: `http://${messengerDom}${cookiePath}`, cookieStr: buildCookieString() });
364
+ cookieConfigs.push({ url: `https://${messengerDom}${cookiePath}`, cookieStr: buildCookieString() });
365
+ cookieConfigs.push({ url: `http://www.${messengerDom}${cookiePath}`, cookieStr: buildCookieString() });
366
+ cookieConfigs.push({ url: `https://www.${messengerDom}${cookiePath}`, cookieStr: buildCookieString() });
367
+ } else {
368
+ // For other domains, set normally
369
+ cookieConfigs.push({ url: `http://${dom}${cookiePath}`, cookieStr: buildCookieString() });
370
+ cookieConfigs.push({ url: `https://${dom}${cookiePath}`, cookieStr: buildCookieString() });
371
+ cookieConfigs.push({ url: `http://www.${dom}${cookiePath}`, cookieStr: buildCookieString() });
372
+ cookieConfigs.push({ url: `https://www.${dom}${cookiePath}`, cookieStr: buildCookieString() });
373
+ }
307
374
 
308
- tasks.push(j.setCookie(str, base1).catch(() => { }));
309
- tasks.push(j.setCookie(str, base2).catch(() => { }));
310
- tasks.push(j.setCookie(str, base3).catch(() => { }));
311
- tasks.push(j.setCookie(str, base4).catch(() => { }));
375
+ // Set cookie for all target URLs, silently catch domain errors
376
+ for (const config of cookieConfigs) {
377
+ tasks.push(j.setCookie(config.cookieStr, config.url).catch((err) => {
378
+ // Silently ignore domain mismatch errors for cross-domain cookies
379
+ // These are expected when setting cookies across domains
380
+ if (err && err.message && err.message.includes("Cookie not in this host's domain")) {
381
+ return; // Expected error, ignore
382
+ }
383
+ // Log other errors but don't throw
384
+ return;
385
+ }));
386
+ }
312
387
  }
313
388
  await Promise.all(tasks);
314
389
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongdev/fca-unofficial",
3
- "version": "3.0.15",
3
+ "version": "3.0.19",
4
4
  "description": "Unofficial Facebook Chat API for Node.js - Interact with Facebook Messenger programmatically",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -24,9 +24,9 @@ module.exports = function (defaultFuncs, api, ctx) {
24
24
  async function uploadAttachment(streams) {
25
25
  const uploads = streams.map(stream => {
26
26
  if (!isReadableStream(stream)) throw { error: "Attachment should be a readable stream and not " + getType(stream) + "." };
27
- const form = { upload_1024: stream, voice_clip: "true" };
27
+ const form = { farr: stream };
28
28
  return defaultFuncs
29
- .postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
29
+ .postFormData("https://www.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
30
30
  .then(parseAndCheckLogin(ctx, defaultFuncs))
31
31
  .then(resData => {
32
32
  if (resData.error) throw resData;
@@ -20,14 +20,13 @@ module.exports = function(defaultFuncs, api, ctx) {
20
20
  }
21
21
 
22
22
  const form = {
23
- upload_1024: attachments[i],
24
- voice_clip: "true"
23
+ farr: attachments[i]
25
24
  };
26
25
 
27
26
  uploads.push(
28
27
  defaultFuncs
29
28
  .postFormData(
30
- "https://upload.facebook.com/ajax/mercury/upload.php",
29
+ "https://www.facebook.com/ajax/mercury/upload.php",
31
30
  ctx.jar,
32
31
  form,
33
32
  {}