@lazyneoaz/metachat 4.0.6 → 4.0.8
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/dist/index.cjs +608 -78
- package/dist/index.d.mts +298 -1
- package/dist/index.d.ts +298 -1
- package/dist/index.mjs +601 -79
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -25107,13 +25107,15 @@ function getHeaders(url2, options, ctx, customHeader) {
|
|
|
25107
25107
|
headers["priority"] = "u=0, i";
|
|
25108
25108
|
}
|
|
25109
25109
|
if (isXhr) {
|
|
25110
|
-
|
|
25111
|
-
|
|
25112
|
-
|
|
25110
|
+
if (!isGraphQl) {
|
|
25111
|
+
headers["X-Requested-With"] = "XMLHttpRequest";
|
|
25112
|
+
headers["Pragma"] = "no-cache";
|
|
25113
|
+
headers["Cache-Control"] = "no-cache";
|
|
25114
|
+
}
|
|
25113
25115
|
headers["priority"] = "u=1, i";
|
|
25114
25116
|
}
|
|
25115
25117
|
if (isGraphQl) {
|
|
25116
|
-
headers["x-asbd-id"] =
|
|
25118
|
+
headers["x-asbd-id"] = String(ctx?.asbdId || DEFAULT_ASBD_ID);
|
|
25117
25119
|
const lsd = ctx?.lsd || ctx?.fb_lsd;
|
|
25118
25120
|
if (lsd) headers["x-fb-lsd"] = sanitizeHeaderValue2(lsd);
|
|
25119
25121
|
const friendlyName = customHeader?.["x-fb-friendly-name"] || customHeader?.["X-Fb-Friendly-Name"];
|
|
@@ -25184,10 +25186,11 @@ function getFingerprintParams(options) {
|
|
|
25184
25186
|
dpr: String(profile.devicePixelRatio)
|
|
25185
25187
|
};
|
|
25186
25188
|
}
|
|
25187
|
-
var meta;
|
|
25189
|
+
var DEFAULT_ASBD_ID, meta;
|
|
25188
25190
|
var init_headers = __esm({
|
|
25189
25191
|
"src/utils/headers.ts"() {
|
|
25190
25192
|
init_user_agents();
|
|
25193
|
+
DEFAULT_ASBD_ID = "359341";
|
|
25191
25194
|
meta = (prop2) => new RegExp(`<meta property="${prop2}" content="([^"]*)"`);
|
|
25192
25195
|
}
|
|
25193
25196
|
});
|
|
@@ -75525,9 +75528,13 @@ __export(utils_exports2, {
|
|
|
75525
75528
|
NUM_TO_MONTH: () => NUM_TO_MONTH,
|
|
75526
75529
|
NetworkError: () => NetworkError,
|
|
75527
75530
|
NotFoundError: () => NotFoundError,
|
|
75531
|
+
PING_GRACE_MS: () => PING_GRACE_MS,
|
|
75528
75532
|
PermissionError: () => PermissionError,
|
|
75529
75533
|
RateLimitError: () => RateLimitError,
|
|
75534
|
+
RealtimeHealth: () => RealtimeHealth,
|
|
75535
|
+
RecoverySupervisor: () => RecoverySupervisor,
|
|
75530
75536
|
SESSION_COOKIE_NAMES: () => SESSION_COOKIE_NAMES,
|
|
75537
|
+
SILENT_WINDOW_MS: () => SILENT_WINDOW_MS,
|
|
75531
75538
|
TimeoutError: () => TimeoutError,
|
|
75532
75539
|
ValidationError: () => ValidationError,
|
|
75533
75540
|
WINDOW_MS: () => WINDOW_MS,
|
|
@@ -75552,6 +75559,7 @@ __export(utils_exports2, {
|
|
|
75552
75559
|
delay: () => delay2,
|
|
75553
75560
|
ensureCometTokens: () => ensureCometTokens,
|
|
75554
75561
|
error: () => error,
|
|
75562
|
+
extractAsbdId: () => extractAsbdId,
|
|
75555
75563
|
extractAttachmentIds: () => extractAttachmentIds,
|
|
75556
75564
|
extractCookies: () => extractCookies,
|
|
75557
75565
|
extractCookiesFromBody: () => extractCookiesFromBody,
|
|
@@ -75602,6 +75610,7 @@ __export(utils_exports2, {
|
|
|
75602
75610
|
invalidateCometTokens: () => invalidateCometTokens,
|
|
75603
75611
|
isAuthFailure: () => isAuthFailure,
|
|
75604
75612
|
isBreakerOpen: () => isBreakerOpen,
|
|
75613
|
+
isLoggedOutDocument: () => isLoggedOutDocument,
|
|
75605
75614
|
isReadableStream: () => isReadableStream2,
|
|
75606
75615
|
isStaleTokenError: () => isStaleTokenError,
|
|
75607
75616
|
json: () => json2,
|
|
@@ -75639,6 +75648,8 @@ __export(utils_exports2, {
|
|
|
75639
75648
|
setProxy: () => setProxy2,
|
|
75640
75649
|
sleep: () => sleep,
|
|
75641
75650
|
startLiveness: () => startLiveness,
|
|
75651
|
+
startRealtimeSupervisor: () => startRealtimeSupervisor,
|
|
75652
|
+
startRecovery: () => startRecovery,
|
|
75642
75653
|
success: () => success,
|
|
75643
75654
|
tripBreaker: () => tripBreaker,
|
|
75644
75655
|
uploadGroupImage: () => uploadGroupImage,
|
|
@@ -90995,6 +91006,9 @@ function extractLsd(html3) {
|
|
|
90995
91006
|
function extractDtsg(html3) {
|
|
90996
91007
|
return getFrom3(html3, '["DTSGInitialData",[],{"token":"', '"}') || getFrom3(html3, 'name="fb_dtsg" value="', '"') || (html3.match(/"DTSGInitialData",\[\],\{"token":"([^"]+)"/) || [])[1] || "";
|
|
90997
91008
|
}
|
|
91009
|
+
function extractAsbdId(html3) {
|
|
91010
|
+
return (html3.match(/"asbd_id":(\d+)/) || [])[1] || (html3.match(/x-asbd-id["']?\s*[:=]\s*["']?(\d+)/i) || [])[1] || (html3.match(/"ASBD_ID":(\d+)/) || [])[1] || "";
|
|
91011
|
+
}
|
|
90998
91012
|
function extractSpin(html3) {
|
|
90999
91013
|
const out = {};
|
|
91000
91014
|
const spinB = (html3.match(/"__spin_b":"([^"]+)"/) || [])[1];
|
|
@@ -91061,6 +91075,8 @@ async function ensureCometTokens(ctx, defaultFuncs, force = false) {
|
|
|
91061
91075
|
const spin = extractSpin(html3);
|
|
91062
91076
|
if (Object.keys(spin).length) ctx.__spin = { ...ctx.__spin || {}, ...spin };
|
|
91063
91077
|
if (spin.__rev) ctx.revision = spin.__rev;
|
|
91078
|
+
const asbd = extractAsbdId(html3);
|
|
91079
|
+
if (asbd) ctx.asbdId = asbd;
|
|
91064
91080
|
ctx.lsd = lsd;
|
|
91065
91081
|
ctx.fb_dtsg = dtsg;
|
|
91066
91082
|
ctx.jazoest = recomputeJazoest(dtsg);
|
|
@@ -91331,6 +91347,13 @@ function isAuthFailure(value) {
|
|
|
91331
91347
|
}
|
|
91332
91348
|
return false;
|
|
91333
91349
|
}
|
|
91350
|
+
function isLoggedOutDocument(html3) {
|
|
91351
|
+
if (typeof html3 !== "string" || html3.length < 200) return false;
|
|
91352
|
+
if (!/<html/i.test(html3)) return false;
|
|
91353
|
+
const hasAuthedTokens = /DTSGInitialData|"LSD",\[\]/.test(html3);
|
|
91354
|
+
const looksLikeLogin = /name="(?:email|pass)"|id="email"|"login_form"|LoginForm|login_form/i.test(html3) || /Continue as |Use another profile|Create new account/i.test(html3) || /You must log in to continue|Please log in|log in to continue/i.test(html3);
|
|
91355
|
+
return looksLikeLogin && !hasAuthedTokens;
|
|
91356
|
+
}
|
|
91334
91357
|
async function withSessionRetry(ctx, defaultFuncs, operation, options = {}) {
|
|
91335
91358
|
const attempts = Math.max(1, options.attempts ?? 2);
|
|
91336
91359
|
let lastError;
|
|
@@ -91437,6 +91460,8 @@ async function warmUpSession(ctx, getter, options = {}) {
|
|
|
91437
91460
|
const spin = extractSpin(html3);
|
|
91438
91461
|
if (Object.keys(spin).length) ctx.__spin = { ...ctx.__spin || {}, ...spin };
|
|
91439
91462
|
if (spin.__rev) ctx.revision = spin.__rev;
|
|
91463
|
+
const asbd = extractAsbdId(html3);
|
|
91464
|
+
if (asbd) ctx.asbdId = asbd;
|
|
91440
91465
|
tokensSeeded = true;
|
|
91441
91466
|
}
|
|
91442
91467
|
} else if (url2.includes("/messages")) {
|
|
@@ -91535,6 +91560,339 @@ async function awaitProactiveSlot(ctx, maxWaitMs = 15 * 60 * 1e3) {
|
|
|
91535
91560
|
return false;
|
|
91536
91561
|
}
|
|
91537
91562
|
|
|
91563
|
+
// src/utils/recovery.ts
|
|
91564
|
+
init_pacing();
|
|
91565
|
+
init_safety();
|
|
91566
|
+
var DEFAULTS = {
|
|
91567
|
+
intervalMs: 10 * 60 * 1e3,
|
|
91568
|
+
failureThreshold: 3,
|
|
91569
|
+
maxRecoveries: 5
|
|
91570
|
+
};
|
|
91571
|
+
function randJitter(base, spread3 = 0.3) {
|
|
91572
|
+
return Math.floor(base * (1 - spread3 / 2 + Math.random() * spread3));
|
|
91573
|
+
}
|
|
91574
|
+
var RecoverySupervisor = class {
|
|
91575
|
+
constructor(runtime, options = {}) {
|
|
91576
|
+
this.timer = null;
|
|
91577
|
+
this.stopped = true;
|
|
91578
|
+
this.running = false;
|
|
91579
|
+
this.runtime = runtime;
|
|
91580
|
+
this.opts = {
|
|
91581
|
+
intervalMs: options.intervalMs ?? DEFAULTS.intervalMs,
|
|
91582
|
+
failureThreshold: options.failureThreshold ?? DEFAULTS.failureThreshold,
|
|
91583
|
+
maxRecoveries: options.maxRecoveries ?? DEFAULTS.maxRecoveries,
|
|
91584
|
+
noRelogin: options.noRelogin ?? false
|
|
91585
|
+
};
|
|
91586
|
+
this.backoffMs = this.opts.intervalMs;
|
|
91587
|
+
this.state = {
|
|
91588
|
+
phase: "healthy",
|
|
91589
|
+
checks: 0,
|
|
91590
|
+
consecutiveFailures: 0,
|
|
91591
|
+
healCount: 0,
|
|
91592
|
+
attempts: 0,
|
|
91593
|
+
reloginCount: 0,
|
|
91594
|
+
givenUp: 0,
|
|
91595
|
+
lastHealthyAt: Date.now(),
|
|
91596
|
+
nextCheckMs: 0,
|
|
91597
|
+
canRelogin: typeof runtime.relogin === "function" && !this.opts.noRelogin && (runtime.canRelogin !== void 0 ? runtime.canRelogin : true)
|
|
91598
|
+
};
|
|
91599
|
+
}
|
|
91600
|
+
/** A point-in-time copy of the supervisor state. */
|
|
91601
|
+
snapshot() {
|
|
91602
|
+
return { ...this.state, nextCheckMs: Math.max(0, this.nextCheckAt() - Date.now()) };
|
|
91603
|
+
}
|
|
91604
|
+
isRunning() {
|
|
91605
|
+
return !this.stopped;
|
|
91606
|
+
}
|
|
91607
|
+
/** Start the supervisor. Idempotent. */
|
|
91608
|
+
start() {
|
|
91609
|
+
if (!this.stopped) return;
|
|
91610
|
+
this.stopped = false;
|
|
91611
|
+
if (this.state.phase === "stopped") this.state.phase = "healthy";
|
|
91612
|
+
this.startTimer(false);
|
|
91613
|
+
this.emit("check", "recovery supervisor started");
|
|
91614
|
+
}
|
|
91615
|
+
/** Stop the supervisor and clear any pending timer. */
|
|
91616
|
+
stop() {
|
|
91617
|
+
this.stopped = true;
|
|
91618
|
+
if (this.timer) {
|
|
91619
|
+
clearTimeout(this.timer);
|
|
91620
|
+
this.timer = null;
|
|
91621
|
+
}
|
|
91622
|
+
this.state.phase = "stopped";
|
|
91623
|
+
this.emit("stopped", "recovery supervisor stopped");
|
|
91624
|
+
}
|
|
91625
|
+
/**
|
|
91626
|
+
* Run one health check immediately (used by tests and by `checkNow()`).
|
|
91627
|
+
* Returns the resulting state. Never throws.
|
|
91628
|
+
*/
|
|
91629
|
+
async checkNow() {
|
|
91630
|
+
if (this.running) return this.snapshot();
|
|
91631
|
+
this.running = true;
|
|
91632
|
+
try {
|
|
91633
|
+
await this.runOnce();
|
|
91634
|
+
} catch {
|
|
91635
|
+
} finally {
|
|
91636
|
+
this.running = false;
|
|
91637
|
+
}
|
|
91638
|
+
return this.snapshot();
|
|
91639
|
+
}
|
|
91640
|
+
nextCheckAt() {
|
|
91641
|
+
return this.state.nextCheckMs && this.timer ? Date.now() + this.state.nextCheckMs : 0;
|
|
91642
|
+
}
|
|
91643
|
+
startTimer(delayOverride) {
|
|
91644
|
+
if (this.stopped) return;
|
|
91645
|
+
if (this.timer) {
|
|
91646
|
+
clearTimeout(this.timer);
|
|
91647
|
+
this.timer = null;
|
|
91648
|
+
}
|
|
91649
|
+
const delay3 = delayOverride === false ? this.backoffMs : delayOverride ?? this.backoffMs;
|
|
91650
|
+
const jittered = randJitter(delay3);
|
|
91651
|
+
this.state.nextCheckMs = jittered;
|
|
91652
|
+
this.timer = setTimeout(() => {
|
|
91653
|
+
this.timer = null;
|
|
91654
|
+
this.state.nextCheckMs = 0;
|
|
91655
|
+
void this.checkNow().finally(() => {
|
|
91656
|
+
if (!this.stopped) this.startTimer();
|
|
91657
|
+
});
|
|
91658
|
+
}, jittered);
|
|
91659
|
+
if (this.timer && typeof this.timer.unref === "function") this.timer.unref();
|
|
91660
|
+
}
|
|
91661
|
+
async runOnce() {
|
|
91662
|
+
this.state.checks += 1;
|
|
91663
|
+
this.emit("check", `health check #${this.state.checks}`);
|
|
91664
|
+
let healthy = this.runtime.isAuthenticated();
|
|
91665
|
+
if (healthy && this.runtime.probeLiveness) {
|
|
91666
|
+
try {
|
|
91667
|
+
healthy = await this.runtime.probeLiveness();
|
|
91668
|
+
} catch {
|
|
91669
|
+
healthy = true;
|
|
91670
|
+
}
|
|
91671
|
+
}
|
|
91672
|
+
if (healthy) {
|
|
91673
|
+
this.markHealthy("session authenticated");
|
|
91674
|
+
return;
|
|
91675
|
+
}
|
|
91676
|
+
this.state.consecutiveFailures += 1;
|
|
91677
|
+
this.state.phase = "refreshing";
|
|
91678
|
+
this.emit("unhealthy", `unauthenticated (${this.state.consecutiveFailures}/${this.opts.failureThreshold})`);
|
|
91679
|
+
if (this.state.consecutiveFailures < this.opts.failureThreshold) {
|
|
91680
|
+
return;
|
|
91681
|
+
}
|
|
91682
|
+
if (isBreakerOpen(this.runtime.ctx)) {
|
|
91683
|
+
this.state.phase = "cooling";
|
|
91684
|
+
this.emit("cooling", "safety breaker open; delaying recovery");
|
|
91685
|
+
return;
|
|
91686
|
+
}
|
|
91687
|
+
if (this.state.attempts >= this.opts.maxRecoveries) {
|
|
91688
|
+
this.state.phase = "cooling";
|
|
91689
|
+
this.state.givenUp += 1;
|
|
91690
|
+
this.emit("gave-up", "recovery budget exhausted");
|
|
91691
|
+
return;
|
|
91692
|
+
}
|
|
91693
|
+
this.state.attempts += 1;
|
|
91694
|
+
let healed = false;
|
|
91695
|
+
try {
|
|
91696
|
+
healed = await this.runtime.refresh();
|
|
91697
|
+
} catch {
|
|
91698
|
+
healed = false;
|
|
91699
|
+
}
|
|
91700
|
+
if (healed && this.runtime.isAuthenticated()) {
|
|
91701
|
+
this.state.healCount += 1;
|
|
91702
|
+
this.markHealthy("cookie refresh restored the session");
|
|
91703
|
+
this.afterRecovery();
|
|
91704
|
+
return;
|
|
91705
|
+
}
|
|
91706
|
+
if (!this.state.canRelogin || !this.runtime.relogin) {
|
|
91707
|
+
this.state.phase = "cooling";
|
|
91708
|
+
this.state.givenUp += 1;
|
|
91709
|
+
this.emit(
|
|
91710
|
+
"gave-up",
|
|
91711
|
+
"session unauthenticated and no credentials available for re-login; provide email+password or a fresh appState"
|
|
91712
|
+
);
|
|
91713
|
+
return;
|
|
91714
|
+
}
|
|
91715
|
+
this.state.phase = "relogin";
|
|
91716
|
+
let fresh = null;
|
|
91717
|
+
try {
|
|
91718
|
+
fresh = await this.runtime.relogin();
|
|
91719
|
+
} catch {
|
|
91720
|
+
fresh = null;
|
|
91721
|
+
}
|
|
91722
|
+
if (Array.isArray(fresh) && fresh.length > 0) {
|
|
91723
|
+
this.state.reloginCount += 1;
|
|
91724
|
+
try {
|
|
91725
|
+
this.runtime.persistAppState?.(fresh);
|
|
91726
|
+
} catch {
|
|
91727
|
+
}
|
|
91728
|
+
this.markHealthy("credential re-login succeeded");
|
|
91729
|
+
this.afterRecovery();
|
|
91730
|
+
return;
|
|
91731
|
+
}
|
|
91732
|
+
this.state.phase = "cooling";
|
|
91733
|
+
this.state.givenUp += 1;
|
|
91734
|
+
this.emit("gave-up", "credential re-login did not return a fresh session");
|
|
91735
|
+
}
|
|
91736
|
+
markHealthy(detail) {
|
|
91737
|
+
this.state.phase = "healthy";
|
|
91738
|
+
this.state.consecutiveFailures = 0;
|
|
91739
|
+
this.state.lastHealthyAt = Date.now();
|
|
91740
|
+
this.state.lastDetail = detail;
|
|
91741
|
+
this.backoffMs = this.opts.intervalMs;
|
|
91742
|
+
this.emit("healed", detail);
|
|
91743
|
+
}
|
|
91744
|
+
afterRecovery() {
|
|
91745
|
+
try {
|
|
91746
|
+
this.runtime.restartMqtt?.();
|
|
91747
|
+
} catch {
|
|
91748
|
+
}
|
|
91749
|
+
}
|
|
91750
|
+
emit(type, detail) {
|
|
91751
|
+
if (!this.runtime.onEvent) return;
|
|
91752
|
+
try {
|
|
91753
|
+
this.runtime.onEvent({ type, detail, state: this.snapshot() });
|
|
91754
|
+
} catch {
|
|
91755
|
+
}
|
|
91756
|
+
}
|
|
91757
|
+
};
|
|
91758
|
+
function startRecovery(ctx, runtime, options = {}) {
|
|
91759
|
+
if (ctx.__recovery && typeof ctx.__recovery.stop === "function") {
|
|
91760
|
+
try {
|
|
91761
|
+
ctx.__recovery.stop();
|
|
91762
|
+
} catch {
|
|
91763
|
+
}
|
|
91764
|
+
}
|
|
91765
|
+
const supervisor = new RecoverySupervisor(runtime, options);
|
|
91766
|
+
ctx.__recovery = supervisor;
|
|
91767
|
+
supervisor.start();
|
|
91768
|
+
return supervisor;
|
|
91769
|
+
}
|
|
91770
|
+
|
|
91771
|
+
// src/utils/realtime-health.ts
|
|
91772
|
+
init_pacing();
|
|
91773
|
+
var SILENT_WINDOW_MS = 6 * 60 * 1e3;
|
|
91774
|
+
var PING_GRACE_MS = 45 * 1e3;
|
|
91775
|
+
var RealtimeHealth = class {
|
|
91776
|
+
constructor(now = () => Date.now()) {
|
|
91777
|
+
this.now = now;
|
|
91778
|
+
this.frames = 0;
|
|
91779
|
+
this.lastFrameAt = 0;
|
|
91780
|
+
this.connectedAt = 0;
|
|
91781
|
+
this.probes = 0;
|
|
91782
|
+
this.forcedReconnects = 0;
|
|
91783
|
+
this.lastPingAt = 0;
|
|
91784
|
+
this.startedAt = Date.now();
|
|
91785
|
+
this.startedAt = this.now();
|
|
91786
|
+
}
|
|
91787
|
+
/** Record any inbound frame (message, pong, anything from the broker). */
|
|
91788
|
+
noteFrame() {
|
|
91789
|
+
this.frames += 1;
|
|
91790
|
+
this.lastFrameAt = this.now();
|
|
91791
|
+
}
|
|
91792
|
+
/** Record a successful connect. */
|
|
91793
|
+
noteConnected() {
|
|
91794
|
+
this.connectedAt = this.now();
|
|
91795
|
+
this.lastFrameAt = this.now();
|
|
91796
|
+
}
|
|
91797
|
+
/** Record that the transport reports itself disconnected. */
|
|
91798
|
+
noteDisconnected() {
|
|
91799
|
+
this.lastFrameAt = 0;
|
|
91800
|
+
}
|
|
91801
|
+
/** Record an active ping being sent. */
|
|
91802
|
+
notePing() {
|
|
91803
|
+
this.lastPingAt = this.now();
|
|
91804
|
+
}
|
|
91805
|
+
sinceLastFrame() {
|
|
91806
|
+
const base = this.lastFrameAt || this.connectedAt || this.startedAt;
|
|
91807
|
+
return this.now() - base;
|
|
91808
|
+
}
|
|
91809
|
+
/**
|
|
91810
|
+
* Decide what to do about the current socket.
|
|
91811
|
+
*
|
|
91812
|
+
* - `disconnected` — the transport already knows it is down; reconnect.
|
|
91813
|
+
* - `dead` — connected on paper, silent past the window, and a ping raised no
|
|
91814
|
+
* traffic within the grace period; reconnect.
|
|
91815
|
+
* - `suspect` — silent past the window but a ping was only just sent; wait.
|
|
91816
|
+
* - `quiet` — silent but inside the window; normal.
|
|
91817
|
+
* - `healthy` — recent traffic.
|
|
91818
|
+
*/
|
|
91819
|
+
verdict(connected) {
|
|
91820
|
+
if (!connected) return "disconnected";
|
|
91821
|
+
const silent = this.sinceLastFrame();
|
|
91822
|
+
if (silent < SILENT_WINDOW_MS / 2) return "healthy";
|
|
91823
|
+
if (silent < SILENT_WINDOW_MS) return "quiet";
|
|
91824
|
+
if (this.lastPingAt && this.now() - this.lastPingAt < PING_GRACE_MS) return "suspect";
|
|
91825
|
+
return "dead";
|
|
91826
|
+
}
|
|
91827
|
+
/** A snapshot for diagnostics. */
|
|
91828
|
+
state(connected) {
|
|
91829
|
+
return {
|
|
91830
|
+
connected,
|
|
91831
|
+
sinceLastFrameMs: this.sinceLastFrame(),
|
|
91832
|
+
frames: this.frames,
|
|
91833
|
+
probes: this.probes,
|
|
91834
|
+
forcedReconnects: this.forcedReconnects,
|
|
91835
|
+
verdict: this.verdict(connected)
|
|
91836
|
+
};
|
|
91837
|
+
}
|
|
91838
|
+
noteProbe() {
|
|
91839
|
+
this.probes += 1;
|
|
91840
|
+
}
|
|
91841
|
+
noteForcedReconnect() {
|
|
91842
|
+
this.forcedReconnects += 1;
|
|
91843
|
+
}
|
|
91844
|
+
};
|
|
91845
|
+
function startRealtimeSupervisor(options) {
|
|
91846
|
+
const health = new RealtimeHealth();
|
|
91847
|
+
const interval = options.intervalMs ?? 3 * 60 * 1e3;
|
|
91848
|
+
let stopped = false;
|
|
91849
|
+
let timer = null;
|
|
91850
|
+
const evaluate = () => {
|
|
91851
|
+
const connected = options.isConnected();
|
|
91852
|
+
const verdict = health.verdict(connected);
|
|
91853
|
+
health.noteProbe();
|
|
91854
|
+
if (verdict === "dead") {
|
|
91855
|
+
const pingSent = options.ping ? options.ping() : false;
|
|
91856
|
+
if (pingSent) {
|
|
91857
|
+
health.notePing();
|
|
91858
|
+
} else {
|
|
91859
|
+
health.noteForcedReconnect();
|
|
91860
|
+
options.reconnect("realtime socket silent and unpinnable");
|
|
91861
|
+
}
|
|
91862
|
+
}
|
|
91863
|
+
const state = health.state(connected);
|
|
91864
|
+
try {
|
|
91865
|
+
options.onVerdict?.(state);
|
|
91866
|
+
} catch {
|
|
91867
|
+
}
|
|
91868
|
+
return state;
|
|
91869
|
+
};
|
|
91870
|
+
const schedule = () => {
|
|
91871
|
+
if (stopped) return;
|
|
91872
|
+
timer = setTimeout(
|
|
91873
|
+
() => {
|
|
91874
|
+
timer = null;
|
|
91875
|
+
evaluate();
|
|
91876
|
+
schedule();
|
|
91877
|
+
},
|
|
91878
|
+
Math.max(1e3, humanDelay(interval, interval * 0.3))
|
|
91879
|
+
);
|
|
91880
|
+
if (timer && typeof timer.unref === "function") timer.unref();
|
|
91881
|
+
};
|
|
91882
|
+
schedule();
|
|
91883
|
+
return {
|
|
91884
|
+
health,
|
|
91885
|
+
checkNow: evaluate,
|
|
91886
|
+
stop: () => {
|
|
91887
|
+
stopped = true;
|
|
91888
|
+
if (timer) {
|
|
91889
|
+
clearTimeout(timer);
|
|
91890
|
+
timer = null;
|
|
91891
|
+
}
|
|
91892
|
+
}
|
|
91893
|
+
};
|
|
91894
|
+
}
|
|
91895
|
+
|
|
91538
91896
|
// src/utils/index.ts
|
|
91539
91897
|
async function json2(url2, jar2, qs2, options, ctx, customHeader) {
|
|
91540
91898
|
try {
|
|
@@ -91752,6 +92110,7 @@ async function buildAPI(html3, jar2, netData, globalOptions, fbLinkFunc, errorRe
|
|
|
91752
92110
|
const lsd = lsdConfig && lsdConfig.token || extractLsd(html3) || void 0;
|
|
91753
92111
|
const spin = extractSpin(html3);
|
|
91754
92112
|
const revision = spin.__rev || getFrom(html3, 'revision":', ",").trim();
|
|
92113
|
+
const asbdId = extractAsbdId(html3) || void 0;
|
|
91755
92114
|
const clientIDData = findConfig("MqttWebDeviceID");
|
|
91756
92115
|
const clientID = clientIDData ? clientIDData.clientID : void 0;
|
|
91757
92116
|
const mqttConfigData = findConfig("MqttWebConfig");
|
|
@@ -91793,7 +92152,8 @@ async function buildAPI(html3, jar2, netData, globalOptions, fbLinkFunc, errorRe
|
|
|
91793
92152
|
...dtsgResult,
|
|
91794
92153
|
...lsd ? { lsd } : {},
|
|
91795
92154
|
...Object.keys(spin).length ? { __spin: spin } : {},
|
|
91796
|
-
...revision ? { revision } : {}
|
|
92155
|
+
...revision ? { revision } : {},
|
|
92156
|
+
...asbdId ? { asbdId } : {}
|
|
91797
92157
|
};
|
|
91798
92158
|
if (lsd && dtsg) {
|
|
91799
92159
|
ctx.__cometTokens = { lsd, fb_dtsg: dtsg, fetchedAt: Date.now(), failures: 0 };
|
|
@@ -91802,8 +92162,95 @@ async function buildAPI(html3, jar2, netData, globalOptions, fbLinkFunc, errorRe
|
|
|
91802
92162
|
return [ctx, defaultFuncs, {}];
|
|
91803
92163
|
}
|
|
91804
92164
|
|
|
91805
|
-
// src/core/models/
|
|
92165
|
+
// src/core/models/acquireCookies.ts
|
|
91806
92166
|
init_axios2();
|
|
92167
|
+
function cookieStringFromObject(cookie, index3) {
|
|
92168
|
+
const name = cookie && (cookie.name || cookie.key);
|
|
92169
|
+
if (!name || cookie.value === void 0 || cookie.value === null) {
|
|
92170
|
+
throw new Error(`Invalid appState cookie at index ${index3}.`);
|
|
92171
|
+
}
|
|
92172
|
+
return formatAppStateCookie(cookie);
|
|
92173
|
+
}
|
|
92174
|
+
function writeCookie(jar2, cookieString) {
|
|
92175
|
+
const normalized = cookieString.replace(/;\s*domain=facebook\.com/i, "; domain=.facebook.com").replace(/;\s*domain=messenger\.com/i, "; domain=.messenger.com");
|
|
92176
|
+
const str = /(^|;)\s*domain=/i.test(normalized) ? normalized : `${normalized}; domain=.facebook.com; path=/; Secure; SameSite=None`;
|
|
92177
|
+
try {
|
|
92178
|
+
jar2.setCookieSync(str, "https://facebook.com");
|
|
92179
|
+
return true;
|
|
92180
|
+
} catch {
|
|
92181
|
+
try {
|
|
92182
|
+
jar2.setCookieSync(
|
|
92183
|
+
`${normalized}; domain=.facebook.com; path=/; Secure; SameSite=None`,
|
|
92184
|
+
"https://www.facebook.com"
|
|
92185
|
+
);
|
|
92186
|
+
return true;
|
|
92187
|
+
} catch {
|
|
92188
|
+
return false;
|
|
92189
|
+
}
|
|
92190
|
+
}
|
|
92191
|
+
}
|
|
92192
|
+
async function acquireCookies(jar2, credentials, globalOptions) {
|
|
92193
|
+
const appState = credentials.appState;
|
|
92194
|
+
if (Array.isArray(appState)) {
|
|
92195
|
+
let loaded = 0;
|
|
92196
|
+
appState.forEach((cookie, index3) => {
|
|
92197
|
+
const str = cookieStringFromObject(cookie, index3);
|
|
92198
|
+
if (str.indexOf("=") <= 0) throw new Error(`Invalid appState cookie at index ${index3}.`);
|
|
92199
|
+
if (writeCookie(jar2, str)) loaded++;
|
|
92200
|
+
});
|
|
92201
|
+
return { source: "appState", loaded };
|
|
92202
|
+
}
|
|
92203
|
+
if (typeof appState === "string") {
|
|
92204
|
+
const parts = appState.split(";").map((s) => s.trim()).filter(Boolean);
|
|
92205
|
+
let loaded = 0;
|
|
92206
|
+
parts.forEach((str, index3) => {
|
|
92207
|
+
if (str.indexOf("=") <= 0) throw new Error(`Invalid appState cookie at index ${index3}.`);
|
|
92208
|
+
if (writeCookie(jar2, str)) loaded++;
|
|
92209
|
+
});
|
|
92210
|
+
return { source: "appStateString", loaded };
|
|
92211
|
+
}
|
|
92212
|
+
if (credentials.email && credentials.password) {
|
|
92213
|
+
const url2 = "https://api.facebook.com/method/auth.login";
|
|
92214
|
+
const params = {
|
|
92215
|
+
access_token: "350685531728|62f8ce9f74b12f84c123cc23437a4a32",
|
|
92216
|
+
format: "json",
|
|
92217
|
+
sdk_version: 2,
|
|
92218
|
+
email: credentials.email,
|
|
92219
|
+
locale: "en_US",
|
|
92220
|
+
password: credentials.password,
|
|
92221
|
+
generate_session_cookies: 1,
|
|
92222
|
+
sig: "c1c640010993db92e5afd11634ced864"
|
|
92223
|
+
};
|
|
92224
|
+
const xurl = `${url2}?${qs.stringify(params)}`;
|
|
92225
|
+
try {
|
|
92226
|
+
const legacyHeaders = getHeaders(url2, globalOptions, null, {
|
|
92227
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
92228
|
+
});
|
|
92229
|
+
const resp = await axios_default.get(xurl, {
|
|
92230
|
+
headers: legacyHeaders,
|
|
92231
|
+
timeout: 6e4,
|
|
92232
|
+
validateStatus: (status) => status >= 200 && status < 600
|
|
92233
|
+
});
|
|
92234
|
+
if (resp.status !== 200) throw new Error("Wrong password / email");
|
|
92235
|
+
const sessionCookies = resp.data["session_cookies"] || [];
|
|
92236
|
+
if (!sessionCookies.length) throw new Error("No session cookies returned");
|
|
92237
|
+
let loaded = 0;
|
|
92238
|
+
for (const c of sessionCookies) {
|
|
92239
|
+
const str = `${c.name}=${c.value}; domain=.facebook.com; path=/; Secure; SameSite=None`;
|
|
92240
|
+
try {
|
|
92241
|
+
jar2.setCookieSync(str, "https://facebook.com");
|
|
92242
|
+
loaded++;
|
|
92243
|
+
} catch {
|
|
92244
|
+
}
|
|
92245
|
+
}
|
|
92246
|
+
if (loaded === 0) throw new Error("No session cookies could be stored");
|
|
92247
|
+
return { source: "credentials", loaded };
|
|
92248
|
+
} catch (e) {
|
|
92249
|
+
throw new Error(e && e.message ? e.message : "Wrong password / email");
|
|
92250
|
+
}
|
|
92251
|
+
}
|
|
92252
|
+
throw new Error("No cookie or credentials found. Please provide cookies or credentials.");
|
|
92253
|
+
}
|
|
91807
92254
|
|
|
91808
92255
|
// src/deltas/apis/extra/addExternalModule.ts
|
|
91809
92256
|
function addExternalModule_default(defaultFuncs, api, ctx) {
|
|
@@ -100404,7 +100851,9 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100404
100851
|
attempts: 0,
|
|
100405
100852
|
delay: MQTT_CONFIG.INITIAL_RETRY_DELAY,
|
|
100406
100853
|
throttleDelay: MQTT_CONFIG.THROTTLE_DELAY,
|
|
100407
|
-
generation: 0
|
|
100854
|
+
generation: 0,
|
|
100855
|
+
health: null,
|
|
100856
|
+
healthSupervisor: null
|
|
100408
100857
|
};
|
|
100409
100858
|
const log2 = (...args) => log(...args);
|
|
100410
100859
|
function clearReconnectTimer() {
|
|
@@ -100418,6 +100867,13 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100418
100867
|
clearInterval(lifecycle.presenceInterval);
|
|
100419
100868
|
lifecycle.presenceInterval = null;
|
|
100420
100869
|
}
|
|
100870
|
+
if (lifecycle.healthSupervisor) {
|
|
100871
|
+
try {
|
|
100872
|
+
lifecycle.healthSupervisor.stop();
|
|
100873
|
+
} catch (_3) {
|
|
100874
|
+
}
|
|
100875
|
+
lifecycle.healthSupervisor = null;
|
|
100876
|
+
}
|
|
100421
100877
|
clearReconnectTimer();
|
|
100422
100878
|
}
|
|
100423
100879
|
function destroyClient() {
|
|
@@ -100545,6 +101001,8 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100545
101001
|
});
|
|
100546
101002
|
lifecycle.client = client2;
|
|
100547
101003
|
ctx.mqttClient = client2;
|
|
101004
|
+
const health = new RealtimeHealth();
|
|
101005
|
+
lifecycle.health = health;
|
|
100548
101006
|
let connected = false;
|
|
100549
101007
|
let closing = false;
|
|
100550
101008
|
let throttled = false;
|
|
@@ -100564,12 +101022,14 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100564
101022
|
if (generation !== lifecycle.generation) return;
|
|
100565
101023
|
connected = false;
|
|
100566
101024
|
ctx.mqttConnected = false;
|
|
101025
|
+
health.noteDisconnected();
|
|
100567
101026
|
});
|
|
100568
101027
|
client2.on("close", () => {
|
|
100569
101028
|
if (generation !== lifecycle.generation) return;
|
|
100570
101029
|
if (connected) log2("MQTT connection closed.");
|
|
100571
101030
|
connected = false;
|
|
100572
101031
|
ctx.mqttConnected = false;
|
|
101032
|
+
health.noteDisconnected();
|
|
100573
101033
|
if (closing) return;
|
|
100574
101034
|
closing = true;
|
|
100575
101035
|
if (authFailure) {
|
|
@@ -100587,6 +101047,7 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100587
101047
|
client2.on("connect", () => {
|
|
100588
101048
|
if (generation !== lifecycle.generation) return;
|
|
100589
101049
|
connected = true;
|
|
101050
|
+
health.noteConnected();
|
|
100590
101051
|
client2.subscribe(MQTT_TOPICS, (subErr) => {
|
|
100591
101052
|
if (subErr) {
|
|
100592
101053
|
error("Failed to subscribe to MQTT topics:", subErr);
|
|
@@ -100623,6 +101084,49 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100623
101084
|
ctx.mqttConnected = true;
|
|
100624
101085
|
ctx.lastMqttError = null;
|
|
100625
101086
|
resetBackoff();
|
|
101087
|
+
if (lifecycle.healthSupervisor) {
|
|
101088
|
+
try {
|
|
101089
|
+
lifecycle.healthSupervisor.stop();
|
|
101090
|
+
} catch (_3) {
|
|
101091
|
+
}
|
|
101092
|
+
}
|
|
101093
|
+
lifecycle.healthSupervisor = startRealtimeSupervisor({
|
|
101094
|
+
isConnected: () => generation === lifecycle.generation && client2.connected,
|
|
101095
|
+
reconnect: (reason) => {
|
|
101096
|
+
if (generation !== lifecycle.generation) return;
|
|
101097
|
+
if (lifecycle.stopped || ctx.loggedIn === false) return;
|
|
101098
|
+
log2(`MQTT ${reason}; recycling the socket`);
|
|
101099
|
+
try {
|
|
101100
|
+
client2.end(true);
|
|
101101
|
+
} catch (_3) {
|
|
101102
|
+
}
|
|
101103
|
+
const gen = generation;
|
|
101104
|
+
setTimeout(() => {
|
|
101105
|
+
if (gen !== lifecycle.generation) return;
|
|
101106
|
+
if (lifecycle.stopped || ctx.loggedIn === false) return;
|
|
101107
|
+
if (lifecycle.client && lifecycle.client.connected) return;
|
|
101108
|
+
if (lifecycle.reconnectTimer) return;
|
|
101109
|
+
scheduleReconnect("realtime socket recycled");
|
|
101110
|
+
}, 5e3).unref?.();
|
|
101111
|
+
},
|
|
101112
|
+
ping: () => {
|
|
101113
|
+
try {
|
|
101114
|
+
client2.ping();
|
|
101115
|
+
return true;
|
|
101116
|
+
} catch {
|
|
101117
|
+
return false;
|
|
101118
|
+
}
|
|
101119
|
+
},
|
|
101120
|
+
onVerdict: (state) => {
|
|
101121
|
+
if (state.verdict === "dead") {
|
|
101122
|
+
warn(
|
|
101123
|
+
"MQTT health",
|
|
101124
|
+
`silent for ${Math.round(state.sinceLastFrameMs / 1e3)}s; probing`
|
|
101125
|
+
);
|
|
101126
|
+
}
|
|
101127
|
+
}
|
|
101128
|
+
});
|
|
101129
|
+
ctx.__mqttHealth = () => lifecycle.health ? lifecycle.health.state(generation === lifecycle.generation && !!client2.connected) : null;
|
|
100626
101130
|
api.getBotInitialData().then((botData) => {
|
|
100627
101131
|
if (botData) {
|
|
100628
101132
|
log(`Logged in as: ${botData.name || "Facebook User"} (${botData.uid || ctx.userID})`);
|
|
@@ -100633,6 +101137,7 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100633
101137
|
});
|
|
100634
101138
|
client2.on("message", async (topic, message, _packet) => {
|
|
100635
101139
|
try {
|
|
101140
|
+
health.noteFrame();
|
|
100636
101141
|
ctx.lastMessageTime = Date.now();
|
|
100637
101142
|
ctx.messageCount = (ctx.messageCount || 0) + 1;
|
|
100638
101143
|
const jsonMessage = JSON.parse(message.toString());
|
|
@@ -100718,6 +101223,16 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
100718
101223
|
this.stop();
|
|
100719
101224
|
if (typeof cb === "function") cb();
|
|
100720
101225
|
}
|
|
101226
|
+
/** Live connection-health snapshot, for diagnostics/alerting. */
|
|
101227
|
+
getHealth() {
|
|
101228
|
+
if (!lifecycle.health) return null;
|
|
101229
|
+
const connected = !lifecycle.stopped && !!lifecycle.client && !!lifecycle.client.connected;
|
|
101230
|
+
return lifecycle.health.state(connected);
|
|
101231
|
+
}
|
|
101232
|
+
/** Is this listener currently stopped? */
|
|
101233
|
+
isStopped() {
|
|
101234
|
+
return lifecycle.stopped;
|
|
101235
|
+
}
|
|
100721
101236
|
}
|
|
100722
101237
|
const msgEmitter = new MessageEmitter();
|
|
100723
101238
|
lifecycle.stopped = false;
|
|
@@ -100886,76 +101401,8 @@ async function loginHelper(credentials, globalOptions, callback, setOptionsFunc,
|
|
|
100886
101401
|
const jar2 = getJar();
|
|
100887
101402
|
log("Logging in...");
|
|
100888
101403
|
const appState = credentials.appState;
|
|
100889
|
-
if (appState) {
|
|
100890
|
-
|
|
100891
|
-
if (Array.isArray(appState)) {
|
|
100892
|
-
cookieStrings = appState.map((c, index3) => {
|
|
100893
|
-
const name = c && (c.name || c.key);
|
|
100894
|
-
if (!name || c.value === void 0 || c.value === null) {
|
|
100895
|
-
throw new Error(`Invalid appState cookie at index ${index3}.`);
|
|
100896
|
-
}
|
|
100897
|
-
return formatAppStateCookie(c);
|
|
100898
|
-
});
|
|
100899
|
-
} else if (typeof appState === "string") {
|
|
100900
|
-
cookieStrings = appState.split(";").map((s) => s.trim()).filter(Boolean);
|
|
100901
|
-
} else {
|
|
100902
|
-
throw new Error(
|
|
100903
|
-
"Invalid appState format. Please provide an array of cookie objects or a cookie string."
|
|
100904
|
-
);
|
|
100905
|
-
}
|
|
100906
|
-
cookieStrings.forEach((cookieString, index3) => {
|
|
100907
|
-
if (cookieString.indexOf("=") <= 0) {
|
|
100908
|
-
throw new Error(`Invalid appState cookie at index ${index3}.`);
|
|
100909
|
-
}
|
|
100910
|
-
const normalized = cookieString.replace(/;\s*domain=facebook\.com/i, "; domain=.facebook.com").replace(/;\s*domain=messenger\.com/i, "; domain=.messenger.com");
|
|
100911
|
-
const str = /(^|;)\s*domain=/i.test(normalized) ? normalized : `${normalized}; domain=.facebook.com; path=/; Secure; SameSite=None`;
|
|
100912
|
-
try {
|
|
100913
|
-
jar2.setCookieSync(str, "https://facebook.com");
|
|
100914
|
-
} catch {
|
|
100915
|
-
try {
|
|
100916
|
-
jar2.setCookieSync(`${normalized}; domain=.facebook.com; path=/; Secure; SameSite=None`, "https://www.facebook.com");
|
|
100917
|
-
} catch {
|
|
100918
|
-
}
|
|
100919
|
-
}
|
|
100920
|
-
});
|
|
100921
|
-
} else if (credentials.email && credentials.password) {
|
|
100922
|
-
const url2 = "https://api.facebook.com/method/auth.login";
|
|
100923
|
-
const params = {
|
|
100924
|
-
access_token: "350685531728|62f8ce9f74b12f84c123cc23437a4a32",
|
|
100925
|
-
format: "json",
|
|
100926
|
-
sdk_version: 2,
|
|
100927
|
-
email: credentials.email,
|
|
100928
|
-
locale: "en_US",
|
|
100929
|
-
password: credentials.password,
|
|
100930
|
-
generate_session_cookies: 1,
|
|
100931
|
-
sig: "c1c640010993db92e5afd11634ced864"
|
|
100932
|
-
};
|
|
100933
|
-
const query = qs.stringify(params);
|
|
100934
|
-
const xurl = `${url2}?${query}`;
|
|
100935
|
-
try {
|
|
100936
|
-
const legacyHeaders = getHeaders(
|
|
100937
|
-
url2,
|
|
100938
|
-
globalOptions,
|
|
100939
|
-
null,
|
|
100940
|
-
{ "Content-Type": "application/x-www-form-urlencoded" }
|
|
100941
|
-
);
|
|
100942
|
-
const resp2 = await axios_default.get(xurl, {
|
|
100943
|
-
headers: legacyHeaders,
|
|
100944
|
-
timeout: 6e4,
|
|
100945
|
-
validateStatus: (status) => status >= 200 && status < 600
|
|
100946
|
-
});
|
|
100947
|
-
if (resp2.status !== 200) {
|
|
100948
|
-
throw new Error("Wrong password / email");
|
|
100949
|
-
}
|
|
100950
|
-
const cstrs = resp2.data["session_cookies"].map((c) => `${c.name}=${c.value}`);
|
|
100951
|
-
cstrs.forEach((cstr) => {
|
|
100952
|
-
const domain = ".facebook.com";
|
|
100953
|
-
const str = `${cstr}; domain=${domain}; path=/; Secure; SameSite=None`;
|
|
100954
|
-
jar2.setCookieSync(str, "https://facebook.com");
|
|
100955
|
-
});
|
|
100956
|
-
} catch (e) {
|
|
100957
|
-
throw new Error("Wrong password / email");
|
|
100958
|
-
}
|
|
101404
|
+
if (appState || credentials.email && credentials.password) {
|
|
101405
|
+
await acquireCookies(jar2, credentials, globalOptions);
|
|
100959
101406
|
} else {
|
|
100960
101407
|
throw new Error("No cookie or credentials found. Please provide cookies or credentials.");
|
|
100961
101408
|
}
|
|
@@ -101094,6 +101541,81 @@ async function loginHelper(credentials, globalOptions, callback, setOptionsFunc,
|
|
|
101094
101541
|
}
|
|
101095
101542
|
}
|
|
101096
101543
|
ctx.__stopCookieKeepAlive = scheduleSessionKeepAlive(ctx, defaultFuncs, 15 * 60 * 1e3);
|
|
101544
|
+
ctx.__credentials = {
|
|
101545
|
+
email: credentials.email,
|
|
101546
|
+
password: credentials.password
|
|
101547
|
+
};
|
|
101548
|
+
ctx.__loginGlobalOptions = globalOptions;
|
|
101549
|
+
ctx.__persistPath = globalOptions.appStatePath;
|
|
101550
|
+
if (globalOptions.recovery !== false) {
|
|
101551
|
+
const recoveryOptions = typeof globalOptions.recovery === "object" ? globalOptions.recovery : {};
|
|
101552
|
+
const supervisor = startRecovery(
|
|
101553
|
+
ctx,
|
|
101554
|
+
{
|
|
101555
|
+
ctx,
|
|
101556
|
+
isAuthenticated: () => hasAuthenticatedSession(ctx.jar),
|
|
101557
|
+
probeLiveness: async () => {
|
|
101558
|
+
try {
|
|
101559
|
+
const res = await defaultFuncs.get(
|
|
101560
|
+
"https://www.facebook.com/",
|
|
101561
|
+
ctx.jar,
|
|
101562
|
+
null,
|
|
101563
|
+
ctx.globalOptions,
|
|
101564
|
+
{ noRef: true }
|
|
101565
|
+
);
|
|
101566
|
+
const html3 = typeof res === "string" ? res : res && res.body;
|
|
101567
|
+
if (typeof html3 !== "string" || !html3) return true;
|
|
101568
|
+
return !isLoggedOutDocument(html3);
|
|
101569
|
+
} catch {
|
|
101570
|
+
return true;
|
|
101571
|
+
}
|
|
101572
|
+
},
|
|
101573
|
+
refresh: () => repairSession(ctx, defaultFuncs),
|
|
101574
|
+
canRelogin: Boolean(credentials.email && credentials.password),
|
|
101575
|
+
relogin: async () => {
|
|
101576
|
+
if (!credentials.email || !credentials.password) return null;
|
|
101577
|
+
await sleep(retryDelay(0, 2e3, 15e3));
|
|
101578
|
+
await acquireCookies(ctx.jar, credentials, globalOptions);
|
|
101579
|
+
await repairSession(ctx, defaultFuncs);
|
|
101580
|
+
if (!hasAuthenticatedSession(ctx.jar)) return null;
|
|
101581
|
+
return getAppState(ctx.jar);
|
|
101582
|
+
},
|
|
101583
|
+
persistAppState: (state) => {
|
|
101584
|
+
const path2 = globalOptions.appStatePath;
|
|
101585
|
+
if (!path2) return;
|
|
101586
|
+
try {
|
|
101587
|
+
const fs2 = __require("fs");
|
|
101588
|
+
fs2.writeFileSync(path2, JSON.stringify(state, null, 2));
|
|
101589
|
+
log(`Recovery: refreshed appState written to ${path2}`);
|
|
101590
|
+
} catch (persistError) {
|
|
101591
|
+
warn("Recovery: could not persist appState:", persistError?.message);
|
|
101592
|
+
}
|
|
101593
|
+
},
|
|
101594
|
+
restartMqtt: () => {
|
|
101595
|
+
try {
|
|
101596
|
+
if (typeof ctx.__restartMqtt === "function") {
|
|
101597
|
+
ctx.__restartMqtt();
|
|
101598
|
+
} else if (typeof ctx.reconnectMqtt === "function" && activeListener) {
|
|
101599
|
+
void ctx.reconnectMqtt();
|
|
101600
|
+
}
|
|
101601
|
+
} catch {
|
|
101602
|
+
}
|
|
101603
|
+
},
|
|
101604
|
+
onEvent: (event) => {
|
|
101605
|
+
if (event.type === "gave-up") {
|
|
101606
|
+
warn("Recovery", event.detail);
|
|
101607
|
+
} else if (event.type === "relogin" || event.type === "healed") {
|
|
101608
|
+
log(`Recovery: ${event.detail}`);
|
|
101609
|
+
}
|
|
101610
|
+
}
|
|
101611
|
+
},
|
|
101612
|
+
recoveryOptions
|
|
101613
|
+
);
|
|
101614
|
+
api.getRecoveryState = () => supervisor.snapshot();
|
|
101615
|
+
api.checkRecoveryNow = () => supervisor.checkNow();
|
|
101616
|
+
api.stopRecovery = () => supervisor.stop();
|
|
101617
|
+
api.startRecovery = () => supervisor.start();
|
|
101618
|
+
}
|
|
101097
101619
|
if (globalOptions.liveness !== false) {
|
|
101098
101620
|
const liveness = startLiveness(ctx, {
|
|
101099
101621
|
foregroundPing: () => log("Session active"),
|
|
@@ -101276,4 +101798,4 @@ lodash/lodash.js:
|
|
|
101276
101798
|
*)
|
|
101277
101799
|
*/
|
|
101278
101800
|
|
|
101279
|
-
export { applySetCookie, awaitProactiveSlot, canActProactively, collectSessionCookies, index_default as default, defaultBrowserProfile, ensureCometTokens, extractCookies, extractCookiesFromBody, extractCookiesFromJar, extractCookiesFromSetCookie, extractCurrentUser, getFingerprintParams, getHeaders, getWebSocketHeaders, hasAuthenticatedSession, humanDelay, invalidateCometTokens, isAuthFailure, isBreakerOpen, isStaleTokenError, login, missingSessionCookies, normalizeBrowserProfile, noteAction, noteAuthFailure, noteCheckpoint, noteRateLimit, paceRequest, public_exports as publicTypes, randomUserAgent, refreshSessionCookies, repairSession, reserveRequest, resetBreaker, resolveProfile, retryDelay, safetySnapshot, sleep, startLiveness, tripBreaker, warmUpSession, withCometTokens, withSessionRetry };
|
|
101801
|
+
export { PING_GRACE_MS, RealtimeHealth, RecoverySupervisor, SILENT_WINDOW_MS, acquireCookies, applySetCookie, awaitProactiveSlot, canActProactively, collectSessionCookies, index_default as default, defaultBrowserProfile, ensureCometTokens, extractCookies, extractCookiesFromBody, extractCookiesFromJar, extractCookiesFromSetCookie, extractCurrentUser, getFingerprintParams, getHeaders, getWebSocketHeaders, hasAuthenticatedSession, humanDelay, invalidateCometTokens, isAuthFailure, isBreakerOpen, isLoggedOutDocument, isStaleTokenError, login, missingSessionCookies, normalizeBrowserProfile, noteAction, noteAuthFailure, noteCheckpoint, noteRateLimit, paceRequest, public_exports as publicTypes, randomUserAgent, refreshSessionCookies, repairSession, reserveRequest, resetBreaker, resolveProfile, retryDelay, safetySnapshot, sleep, startLiveness, startRealtimeSupervisor, startRecovery, tripBreaker, warmUpSession, withCometTokens, withSessionRetry };
|