@openclaw/whatsapp 2026.5.2 → 2026.5.3-beta.1
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/access-control-BQ3tCkH8.js +288 -0
- package/dist/account-config-CNQ33oav.js +47 -0
- package/dist/account-ids-DG18xddX.js +5 -0
- package/dist/accounts-BDqgpFEB.js +116 -0
- package/dist/action-runtime-DTGNgG-i.js +74 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/action-runtime.runtime.js +2 -0
- package/dist/active-listener-N7GFKsuN.js +11 -0
- package/dist/agent-tools-login-DpRxLNRB.js +89 -0
- package/dist/api.js +148 -0
- package/dist/audio-preflight.runtime-Bcdsl_ri.js +7 -0
- package/dist/auth-presence.js +32 -0
- package/dist/auth-store-BjCb50Ry.js +381 -0
- package/dist/channel-DQ-5Xoj9.js +542 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel-react-action-Df20qAy9.js +42 -0
- package/dist/channel.runtime-DKXRnA8x.js +55 -0
- package/dist/channel.setup-DOHR2BGp.js +20 -0
- package/dist/command-policy-O8sRnqUV.js +8 -0
- package/dist/config-schema-Dmo66Ubb.js +27 -0
- package/dist/connection-controller-BiHAsTM8.js +596 -0
- package/dist/connection-controller-registry-D_iIGz5m.js +22 -0
- package/dist/constants-DLGCIbfl.js +4 -0
- package/dist/constants.js +2 -0
- package/dist/contract-api.js +19 -0
- package/dist/creds-files-_2V8jzQa.js +19 -0
- package/dist/directory-config-DVs4ffXu.js +37 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/doctor-A9tXm9Om.js +48 -0
- package/dist/doctor-contract-api.js +10 -0
- package/dist/group-session-contract-B8QBn0I2.js +15 -0
- package/dist/identity-QHAlV7Fu.js +75 -0
- package/dist/index.js +18 -0
- package/dist/legacy-session-surface-api.js +8 -0
- package/dist/legacy-state-migrations-api.js +2 -0
- package/dist/light-runtime-api.js +5 -0
- package/dist/login-DymdrKca.js +52 -0
- package/dist/login-qr-DIS0Iv-7.js +378 -0
- package/dist/login-qr-api.js +2 -0
- package/dist/login-qr-runtime.js +16 -0
- package/dist/monitor-C4Fhg_lD.js +3349 -0
- package/dist/normalize-CWYiGkXw.js +2 -0
- package/dist/normalize-target-BPVHNsM5.js +74 -0
- package/dist/outbound-adapter-BssVnZdz.js +29 -0
- package/dist/outbound-base-Bq1UYEK5.js +119 -0
- package/dist/outbound-media-contract-CGss_QHy.js +163 -0
- package/dist/outbound-payload-test-api.js +2 -0
- package/dist/quoted-message-TENQzyxV.js +108 -0
- package/dist/reaction-level-CRVEVAfi.js +16 -0
- package/dist/reply-resolver.runtime-BRCgoO4C.js +2 -0
- package/dist/resolve-outbound-target-CN-Wo6IY.js +39 -0
- package/dist/rolldown-runtime-RkAeH_Qm.js +27 -0
- package/dist/runtime-6fZ67abR.js +8 -0
- package/dist/runtime-api.js +15 -0
- package/dist/runtime-group-policy-Gp1lQ0at.js +11 -0
- package/dist/secret-contract-api.js +5 -0
- package/dist/security-contract-DqH8JDX6.js +26 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/send-CIyLFxdZ.js +234 -0
- package/dist/session-contract-B0efQf9P.js +27 -0
- package/dist/session-errors-CSuKZPub.js +63 -0
- package/dist/session.runtime-C1eSE_KK.js +13 -0
- package/dist/setup-core-DZKvpzbH.js +46 -0
- package/dist/setup-entry.js +23 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/setup-surface-ieFnIW4g.js +344 -0
- package/dist/shared-D_wzSVar.js +307 -0
- package/dist/state-migrations-DnCdvoYD.js +39 -0
- package/dist/targets.js +2 -0
- package/dist/test-api.js +3 -0
- package/dist/text-runtime-C1zNiZeO.js +116 -0
- package/package.json +14 -6
- package/action-runtime-api.ts +0 -1
- package/action-runtime.runtime.ts +0 -1
- package/api.ts +0 -213
- package/auth-presence.ts +0 -80
- package/channel-config-api.ts +0 -1
- package/channel-plugin-api.ts +0 -3
- package/config-api.ts +0 -4
- package/constants.ts +0 -1
- package/contract-api.ts +0 -29
- package/directory-contract-api.ts +0 -4
- package/doctor-contract-api.ts +0 -8
- package/index.test.ts +0 -13
- package/index.ts +0 -16
- package/legacy-session-surface-api.ts +0 -6
- package/legacy-state-migrations-api.ts +0 -1
- package/light-runtime-api.ts +0 -12
- package/login-qr-api.ts +0 -1
- package/login-qr-runtime.ts +0 -23
- package/outbound-payload-test-api.ts +0 -1
- package/runtime-api.ts +0 -84
- package/secret-contract-api.ts +0 -4
- package/security-contract-api.ts +0 -4
- package/setup-entry.test.ts +0 -21
- package/setup-entry.ts +0 -21
- package/setup-plugin-api.ts +0 -3
- package/src/account-config.ts +0 -77
- package/src/account-ids.ts +0 -13
- package/src/account-types.ts +0 -5
- package/src/accounts.test.ts +0 -182
- package/src/accounts.ts +0 -176
- package/src/accounts.whatsapp-auth.test.ts +0 -59
- package/src/action-runtime-target-auth.ts +0 -27
- package/src/action-runtime.test.ts +0 -330
- package/src/action-runtime.ts +0 -76
- package/src/active-listener.test.ts +0 -65
- package/src/active-listener.ts +0 -17
- package/src/agent-tools-login.test.ts +0 -81
- package/src/agent-tools-login.ts +0 -113
- package/src/approval-auth.test.ts +0 -24
- package/src/approval-auth.ts +0 -27
- package/src/auth-store.runtime.ts +0 -1
- package/src/auth-store.test.ts +0 -311
- package/src/auth-store.ts +0 -502
- package/src/auto-reply/config.runtime.ts +0 -16
- package/src/auto-reply/constants.ts +0 -1
- package/src/auto-reply/deliver-reply.test.ts +0 -843
- package/src/auto-reply/deliver-reply.ts +0 -279
- package/src/auto-reply/loggers.ts +0 -6
- package/src/auto-reply/mentions.ts +0 -131
- package/src/auto-reply/monitor/ack-reaction.test.ts +0 -170
- package/src/auto-reply/monitor/ack-reaction.ts +0 -99
- package/src/auto-reply/monitor/audio-preflight.runtime.ts +0 -9
- package/src/auto-reply/monitor/broadcast.ts +0 -153
- package/src/auto-reply/monitor/commands.ts +0 -19
- package/src/auto-reply/monitor/echo.ts +0 -64
- package/src/auto-reply/monitor/group-activation.runtime.ts +0 -1
- package/src/auto-reply/monitor/group-activation.test.ts +0 -189
- package/src/auto-reply/monitor/group-activation.ts +0 -73
- package/src/auto-reply/monitor/group-gating.audio-preflight.test.ts +0 -103
- package/src/auto-reply/monitor/group-gating.runtime.ts +0 -8
- package/src/auto-reply/monitor/group-gating.ts +0 -217
- package/src/auto-reply/monitor/group-members.test.ts +0 -56
- package/src/auto-reply/monitor/group-members.ts +0 -65
- package/src/auto-reply/monitor/inbound-context.test.ts +0 -97
- package/src/auto-reply/monitor/inbound-context.ts +0 -92
- package/src/auto-reply/monitor/inbound-dispatch.runtime.ts +0 -21
- package/src/auto-reply/monitor/inbound-dispatch.test.ts +0 -895
- package/src/auto-reply/monitor/inbound-dispatch.ts +0 -422
- package/src/auto-reply/monitor/last-route.test.ts +0 -37
- package/src/auto-reply/monitor/last-route.ts +0 -61
- package/src/auto-reply/monitor/message-line.runtime.ts +0 -38
- package/src/auto-reply/monitor/message-line.ts +0 -54
- package/src/auto-reply/monitor/on-message.audio-preflight.test.ts +0 -354
- package/src/auto-reply/monitor/on-message.ts +0 -291
- package/src/auto-reply/monitor/peer.ts +0 -17
- package/src/auto-reply/monitor/process-message.audio-preflight.test.ts +0 -420
- package/src/auto-reply/monitor/process-message.test.ts +0 -355
- package/src/auto-reply/monitor/process-message.ts +0 -531
- package/src/auto-reply/monitor/runtime-api.ts +0 -30
- package/src/auto-reply/monitor-state.test.ts +0 -64
- package/src/auto-reply/monitor-state.ts +0 -106
- package/src/auto-reply/monitor.ts +0 -600
- package/src/auto-reply/reply-resolver.runtime.ts +0 -1
- package/src/auto-reply/types.ts +0 -48
- package/src/auto-reply/util.ts +0 -63
- package/src/auto-reply/web-auto-reply-monitor.test.ts +0 -687
- package/src/auto-reply/web-auto-reply-utils.test.ts +0 -392
- package/src/auto-reply.broadcast-groups.combined.test.ts +0 -246
- package/src/auto-reply.broadcast-groups.test-harness.ts +0 -47
- package/src/auto-reply.impl.ts +0 -6
- package/src/auto-reply.test-harness.ts +0 -421
- package/src/auto-reply.ts +0 -1
- package/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts +0 -427
- package/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts +0 -908
- package/src/auto-reply.web-auto-reply.last-route.test.ts +0 -184
- package/src/channel-actions.runtime.ts +0 -7
- package/src/channel-actions.test.ts +0 -216
- package/src/channel-actions.ts +0 -84
- package/src/channel-outbound.test.ts +0 -131
- package/src/channel-outbound.ts +0 -36
- package/src/channel-react-action.runtime.ts +0 -7
- package/src/channel-react-action.test.ts +0 -294
- package/src/channel-react-action.ts +0 -84
- package/src/channel.runtime.ts +0 -117
- package/src/channel.setup.test.ts +0 -461
- package/src/channel.setup.ts +0 -28
- package/src/channel.ts +0 -339
- package/src/command-policy.ts +0 -7
- package/src/config-accessors.test.ts +0 -34
- package/src/config-accessors.ts +0 -22
- package/src/config-schema.test.ts +0 -121
- package/src/config-schema.ts +0 -6
- package/src/config-ui-hints.ts +0 -24
- package/src/connection-controller-registry.test.ts +0 -27
- package/src/connection-controller-registry.ts +0 -49
- package/src/connection-controller.test.ts +0 -282
- package/src/connection-controller.ts +0 -679
- package/src/creds-files.ts +0 -19
- package/src/creds-persistence.ts +0 -102
- package/src/directory-config.test.ts +0 -60
- package/src/directory-config.ts +0 -40
- package/src/directory-contract.test.ts +0 -56
- package/src/doctor-contract.ts +0 -11
- package/src/doctor.test.ts +0 -74
- package/src/doctor.ts +0 -56
- package/src/group-intro.ts +0 -15
- package/src/group-policy.test.ts +0 -36
- package/src/group-policy.ts +0 -40
- package/src/group-session-contract.ts +0 -20
- package/src/group-session-key.test.ts +0 -53
- package/src/group-session-key.ts +0 -41
- package/src/heartbeat.ts +0 -34
- package/src/identity.ts +0 -164
- package/src/inbound/access-control.test-harness.ts +0 -37
- package/src/inbound/access-control.test.ts +0 -375
- package/src/inbound/access-control.ts +0 -237
- package/src/inbound/dedupe.ts +0 -132
- package/src/inbound/extract.test.ts +0 -282
- package/src/inbound/extract.ts +0 -488
- package/src/inbound/lifecycle.ts +0 -39
- package/src/inbound/media.node.test.ts +0 -83
- package/src/inbound/media.ts +0 -102
- package/src/inbound/monitor.ts +0 -890
- package/src/inbound/runtime-api.ts +0 -7
- package/src/inbound/save-media.runtime.ts +0 -1
- package/src/inbound/send-api.test.ts +0 -319
- package/src/inbound/send-api.ts +0 -145
- package/src/inbound/send-result.ts +0 -61
- package/src/inbound/types.ts +0 -106
- package/src/inbound-context.contract.test.ts +0 -32
- package/src/inbound-policy.ts +0 -231
- package/src/inbound.media.test.ts +0 -320
- package/src/inbound.test.ts +0 -290
- package/src/inbound.ts +0 -9
- package/src/login-qr.test.ts +0 -483
- package/src/login-qr.ts +0 -542
- package/src/login.coverage.test.ts +0 -133
- package/src/login.test.ts +0 -89
- package/src/login.ts +0 -70
- package/src/logout.test.ts +0 -162
- package/src/media.test.ts +0 -480
- package/src/media.ts +0 -10
- package/src/monitor-inbox.allows-messages-from-senders-allowfrom-list.test-support.ts +0 -400
- package/src/monitor-inbox.append-upsert.test-support.ts +0 -133
- package/src/monitor-inbox.behavior.test.ts +0 -5
- package/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test-support.ts +0 -362
- package/src/monitor-inbox.captures-media-path-image-messages.test-support.ts +0 -306
- package/src/monitor-inbox.streams-inbound-messages.test-support.ts +0 -729
- package/src/monitor-inbox.test-harness.ts +0 -304
- package/src/normalize-target.ts +0 -123
- package/src/normalize.ts +0 -7
- package/src/outbound-adapter.poll.test.ts +0 -62
- package/src/outbound-adapter.sendpayload.test.ts +0 -195
- package/src/outbound-adapter.ts +0 -36
- package/src/outbound-base.test.ts +0 -560
- package/src/outbound-base.ts +0 -244
- package/src/outbound-media-contract.ts +0 -278
- package/src/outbound-media.runtime.ts +0 -36
- package/src/outbound-payload.contract.test.ts +0 -61
- package/src/outbound-send-deps.ts +0 -1
- package/src/outbound-test-support.ts +0 -16
- package/src/pairing-security.test-harness.ts +0 -59
- package/src/qr-image.ts +0 -1
- package/src/qr-terminal.ts +0 -1
- package/src/quoted-message.test.ts +0 -83
- package/src/quoted-message.ts +0 -184
- package/src/reaction-level.test.ts +0 -94
- package/src/reaction-level.ts +0 -21
- package/src/reconnect.test.ts +0 -51
- package/src/reconnect.ts +0 -55
- package/src/resolve-outbound-target.test.ts +0 -288
- package/src/resolve-outbound-target.ts +0 -58
- package/src/resolve-target.test.ts +0 -120
- package/src/runtime-api.ts +0 -59
- package/src/runtime-group-policy.ts +0 -16
- package/src/runtime.ts +0 -9
- package/src/security-contract.ts +0 -47
- package/src/security-fix.ts +0 -71
- package/src/send.test.ts +0 -534
- package/src/send.ts +0 -292
- package/src/session-contract.test.ts +0 -31
- package/src/session-contract.ts +0 -43
- package/src/session-errors.ts +0 -125
- package/src/session-route.test.ts +0 -41
- package/src/session-route.ts +0 -32
- package/src/session.runtime.ts +0 -8
- package/src/session.test.ts +0 -559
- package/src/session.ts +0 -330
- package/src/setup-core.ts +0 -52
- package/src/setup-finalize.ts +0 -446
- package/src/setup-surface.test.ts +0 -367
- package/src/setup-surface.ts +0 -69
- package/src/setup-test-helpers.ts +0 -216
- package/src/shared.ts +0 -291
- package/src/socket-timing.test.ts +0 -49
- package/src/socket-timing.ts +0 -38
- package/src/state-migrations.ts +0 -54
- package/src/status-issues.test.ts +0 -137
- package/src/status-issues.ts +0 -185
- package/src/system-prompt.test.ts +0 -199
- package/src/system-prompt.ts +0 -31
- package/src/targets-runtime.ts +0 -180
- package/src/test-helpers.ts +0 -690
- package/src/text-runtime.test.ts +0 -162
- package/src/text-runtime.ts +0 -11
- package/src/vcard.ts +0 -84
- package/targets.ts +0 -5
- package/test-api.ts +0 -2
- package/tsconfig.json +0 -16
package/src/login.test.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "node:events";
|
|
2
|
-
import { resetLogger, setLoggerOverride } from "openclaw/plugin-sdk/runtime-env";
|
|
3
|
-
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
import { renderQrPngBase64 } from "./qr-image.js";
|
|
5
|
-
|
|
6
|
-
vi.mock("./session.js", async () => {
|
|
7
|
-
const actual = await vi.importActual<typeof import("./session.js")>("./session.js");
|
|
8
|
-
const ev = new EventEmitter();
|
|
9
|
-
const sock = {
|
|
10
|
-
ev,
|
|
11
|
-
ws: { close: vi.fn() },
|
|
12
|
-
sendPresenceUpdate: vi.fn(),
|
|
13
|
-
sendMessage: vi.fn(),
|
|
14
|
-
};
|
|
15
|
-
return {
|
|
16
|
-
...actual,
|
|
17
|
-
createWaSocket: vi.fn().mockResolvedValue(sock),
|
|
18
|
-
waitForWaConnection: vi.fn().mockResolvedValue(undefined),
|
|
19
|
-
};
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
vi.mock("./auth-store.js", async () => {
|
|
23
|
-
const actual = await vi.importActual<typeof import("./auth-store.js")>("./auth-store.js");
|
|
24
|
-
return {
|
|
25
|
-
...actual,
|
|
26
|
-
restoreCredsFromBackupIfNeeded: vi.fn(async () => false),
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
import type { waitForWaConnection } from "./session.js";
|
|
31
|
-
let loginWeb: typeof import("./login.js").loginWeb;
|
|
32
|
-
let createWaSocket: typeof import("./session.js").createWaSocket;
|
|
33
|
-
let restoreCredsFromBackupIfNeeded: typeof import("./auth-store.js").restoreCredsFromBackupIfNeeded;
|
|
34
|
-
|
|
35
|
-
describe("web login", () => {
|
|
36
|
-
beforeAll(async () => {
|
|
37
|
-
({ loginWeb } = await import("./login.js"));
|
|
38
|
-
({ createWaSocket } = await import("./session.js"));
|
|
39
|
-
({ restoreCredsFromBackupIfNeeded } = await import("./auth-store.js"));
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
vi.useFakeTimers();
|
|
44
|
-
vi.clearAllMocks();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
vi.useRealTimers();
|
|
49
|
-
resetLogger();
|
|
50
|
-
setLoggerOverride(null);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("loginWeb waits for connection and closes", async () => {
|
|
54
|
-
const sock = await (
|
|
55
|
-
createWaSocket as unknown as () => Promise<{ ws: { close: () => void } }>
|
|
56
|
-
)();
|
|
57
|
-
const close = vi.spyOn(sock.ws, "close");
|
|
58
|
-
const waiter: typeof waitForWaConnection = vi.fn().mockResolvedValue(undefined);
|
|
59
|
-
await loginWeb(false, waiter);
|
|
60
|
-
expect(close).not.toHaveBeenCalled();
|
|
61
|
-
|
|
62
|
-
await vi.advanceTimersByTimeAsync(499);
|
|
63
|
-
expect(close).not.toHaveBeenCalled();
|
|
64
|
-
|
|
65
|
-
await vi.advanceTimersByTimeAsync(1);
|
|
66
|
-
expect(close).toHaveBeenCalledTimes(1);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("prints a backup recovery success message when creds are restored from backup", async () => {
|
|
70
|
-
const waiter: typeof waitForWaConnection = vi.fn().mockResolvedValue(undefined);
|
|
71
|
-
const consoleLog = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
72
|
-
vi.mocked(restoreCredsFromBackupIfNeeded).mockResolvedValueOnce(true);
|
|
73
|
-
|
|
74
|
-
await loginWeb(false, waiter);
|
|
75
|
-
|
|
76
|
-
expect(consoleLog).toHaveBeenCalledWith(
|
|
77
|
-
expect.stringContaining("✅ Recovered from creds.json.bak; web session ready."),
|
|
78
|
-
);
|
|
79
|
-
consoleLog.mockRestore();
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe("renderQrPngBase64", () => {
|
|
84
|
-
it("renders a PNG data payload", async () => {
|
|
85
|
-
const b64 = await renderQrPngBase64("openclaw");
|
|
86
|
-
const buf = Buffer.from(b64, "base64");
|
|
87
|
-
expect(buf.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a");
|
|
88
|
-
});
|
|
89
|
-
});
|
package/src/login.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
|
|
2
|
-
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
3
|
-
import { danger, success } from "openclaw/plugin-sdk/runtime-env";
|
|
4
|
-
import { defaultRuntime, type RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
|
5
|
-
import { logInfo } from "openclaw/plugin-sdk/text-runtime";
|
|
6
|
-
import { resolveWhatsAppAccount } from "./accounts.js";
|
|
7
|
-
import { restoreCredsFromBackupIfNeeded } from "./auth-store.js";
|
|
8
|
-
import { closeWaSocketSoon, waitForWhatsAppLoginResult } from "./connection-controller.js";
|
|
9
|
-
import { createWaSocket, waitForWaConnection } from "./session.js";
|
|
10
|
-
import { resolveWhatsAppSocketTiming } from "./socket-timing.js";
|
|
11
|
-
|
|
12
|
-
export async function loginWeb(
|
|
13
|
-
verbose: boolean,
|
|
14
|
-
waitForConnection?: typeof waitForWaConnection,
|
|
15
|
-
runtime: RuntimeEnv = defaultRuntime,
|
|
16
|
-
accountId?: string,
|
|
17
|
-
) {
|
|
18
|
-
const cfg = getRuntimeConfig();
|
|
19
|
-
const account = resolveWhatsAppAccount({ cfg, accountId });
|
|
20
|
-
const socketTiming = resolveWhatsAppSocketTiming(cfg);
|
|
21
|
-
const restoredFromBackup = await restoreCredsFromBackupIfNeeded(account.authDir);
|
|
22
|
-
let sock = await createWaSocket(true, verbose, {
|
|
23
|
-
authDir: account.authDir,
|
|
24
|
-
...socketTiming,
|
|
25
|
-
});
|
|
26
|
-
logInfo("Waiting for WhatsApp connection...", runtime);
|
|
27
|
-
try {
|
|
28
|
-
const result = await waitForWhatsAppLoginResult({
|
|
29
|
-
sock,
|
|
30
|
-
authDir: account.authDir,
|
|
31
|
-
isLegacyAuthDir: account.isLegacyAuthDir,
|
|
32
|
-
verbose,
|
|
33
|
-
runtime,
|
|
34
|
-
waitForConnection,
|
|
35
|
-
socketTiming,
|
|
36
|
-
onSocketReplaced: (replacementSock) => {
|
|
37
|
-
sock = replacementSock;
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
if (result.outcome === "connected") {
|
|
41
|
-
console.log(
|
|
42
|
-
success(
|
|
43
|
-
result.restarted
|
|
44
|
-
? "✅ Linked after restart; web session ready."
|
|
45
|
-
: restoredFromBackup
|
|
46
|
-
? "✅ Recovered from creds.json.bak; web session ready."
|
|
47
|
-
: "✅ Linked! Credentials saved for future sends.",
|
|
48
|
-
),
|
|
49
|
-
);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (result.outcome === "logged-out") {
|
|
54
|
-
console.error(
|
|
55
|
-
danger(
|
|
56
|
-
`WhatsApp reported the session is logged out. Cleared cached web session; please rerun ${formatCliCommand("openclaw channels login")} and scan the QR again.`,
|
|
57
|
-
),
|
|
58
|
-
);
|
|
59
|
-
throw new Error("Session logged out; cache cleared. Re-run login.", {
|
|
60
|
-
cause: result.error,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
console.error(danger(`WhatsApp Web connection ended before fully opening. ${result.message}`));
|
|
65
|
-
throw new Error(result.message, { cause: result.error });
|
|
66
|
-
} finally {
|
|
67
|
-
// Let Baileys flush any final events before closing the socket.
|
|
68
|
-
closeWaSocketSoon(sock);
|
|
69
|
-
}
|
|
70
|
-
}
|
package/src/logout.test.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import fsPromises from "node:fs/promises";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
-
|
|
7
|
-
const runtime = {
|
|
8
|
-
log: vi.fn(),
|
|
9
|
-
error: vi.fn(),
|
|
10
|
-
exit: vi.fn(),
|
|
11
|
-
};
|
|
12
|
-
const WEB_LOGOUT_TEST_TIMEOUT_MS = 15_000;
|
|
13
|
-
|
|
14
|
-
describe("web logout", () => {
|
|
15
|
-
let fixtureRoot = "";
|
|
16
|
-
let previousOAuthDir: string | undefined;
|
|
17
|
-
let caseId = 0;
|
|
18
|
-
let logoutWeb: typeof import("./auth-store.js").logoutWeb;
|
|
19
|
-
|
|
20
|
-
beforeAll(async () => {
|
|
21
|
-
fixtureRoot = await fsPromises.mkdtemp(path.join(os.tmpdir(), "openclaw-test-web-logout-"));
|
|
22
|
-
previousOAuthDir = process.env.OPENCLAW_OAUTH_DIR;
|
|
23
|
-
process.env.OPENCLAW_OAUTH_DIR = path.join(fixtureRoot, "oauth");
|
|
24
|
-
({ logoutWeb } = await import("./auth-store.js"));
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
afterAll(async () => {
|
|
28
|
-
if (previousOAuthDir === undefined) {
|
|
29
|
-
delete process.env.OPENCLAW_OAUTH_DIR;
|
|
30
|
-
} else {
|
|
31
|
-
process.env.OPENCLAW_OAUTH_DIR = previousOAuthDir;
|
|
32
|
-
}
|
|
33
|
-
await fsPromises.rm(fixtureRoot, { recursive: true, force: true });
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const makeCaseDir = async () => {
|
|
37
|
-
const dir = path.join(fixtureRoot, "oauth", "whatsapp", `case-${caseId++}`);
|
|
38
|
-
await fsPromises.mkdir(dir, { recursive: true });
|
|
39
|
-
return dir;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const makeExternalCaseDir = async () => {
|
|
43
|
-
const dir = path.join(fixtureRoot, "external", `case-${caseId++}`);
|
|
44
|
-
await fsPromises.mkdir(dir, { recursive: true });
|
|
45
|
-
return dir;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const createAuthCase = async (files: Record<string, string>) => {
|
|
49
|
-
const authDir = await makeCaseDir();
|
|
50
|
-
await Promise.all(
|
|
51
|
-
Object.entries(files).map(async ([name, contents]) => {
|
|
52
|
-
await fsPromises.writeFile(path.join(authDir, name), contents, "utf-8");
|
|
53
|
-
}),
|
|
54
|
-
);
|
|
55
|
-
return authDir;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
beforeEach(() => {
|
|
59
|
-
vi.clearAllMocks();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
afterEach(() => {
|
|
63
|
-
vi.restoreAllMocks();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it(
|
|
67
|
-
"deletes cached credentials when present",
|
|
68
|
-
{ timeout: WEB_LOGOUT_TEST_TIMEOUT_MS },
|
|
69
|
-
async () => {
|
|
70
|
-
const authDir = await createAuthCase({ "creds.json": "{}" });
|
|
71
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
72
|
-
expect(result).toBe(true);
|
|
73
|
-
expect(fs.existsSync(authDir)).toBe(false);
|
|
74
|
-
},
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
it("removes oauth.json too when not using legacy auth dir", async () => {
|
|
78
|
-
const authDir = await createAuthCase({
|
|
79
|
-
"creds.json": "{}",
|
|
80
|
-
"oauth.json": '{"token":true}',
|
|
81
|
-
"session-abc.json": "{}",
|
|
82
|
-
});
|
|
83
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
84
|
-
expect(result).toBe(true);
|
|
85
|
-
expect(fs.existsSync(authDir)).toBe(false);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("no-ops when nothing to delete", { timeout: WEB_LOGOUT_TEST_TIMEOUT_MS }, async () => {
|
|
89
|
-
const authDir = await makeCaseDir();
|
|
90
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
91
|
-
expect(result).toBe(false);
|
|
92
|
-
expect(runtime.log).toHaveBeenCalled();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("keeps shared oauth.json when using legacy auth dir", async () => {
|
|
96
|
-
const credsDir = path.join(fixtureRoot, "oauth");
|
|
97
|
-
await fsPromises.mkdir(credsDir, { recursive: true });
|
|
98
|
-
await fsPromises.writeFile(path.join(credsDir, "creds.json"), "{}", "utf-8");
|
|
99
|
-
await fsPromises.writeFile(path.join(credsDir, "oauth.json"), '{"token":true}', "utf-8");
|
|
100
|
-
await fsPromises.writeFile(path.join(credsDir, "session-abc.json"), "{}", "utf-8");
|
|
101
|
-
|
|
102
|
-
const result = await logoutWeb({
|
|
103
|
-
authDir: credsDir,
|
|
104
|
-
isLegacyAuthDir: true,
|
|
105
|
-
runtime: runtime as never,
|
|
106
|
-
});
|
|
107
|
-
expect(result).toBe(true);
|
|
108
|
-
expect(fs.existsSync(path.join(credsDir, "oauth.json"))).toBe(true);
|
|
109
|
-
expect(fs.existsSync(path.join(credsDir, "creds.json"))).toBe(false);
|
|
110
|
-
expect(fs.existsSync(path.join(credsDir, "session-abc.json"))).toBe(false);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("does not delete custom auth directories outside the OpenClaw auth root", async () => {
|
|
114
|
-
const authDir = await makeExternalCaseDir();
|
|
115
|
-
await fsPromises.mkdir(path.join(authDir, "nested"));
|
|
116
|
-
await fsPromises.writeFile(path.join(authDir, "creds.json"), "{}", "utf-8");
|
|
117
|
-
await fsPromises.writeFile(path.join(authDir, "oauth.json"), '{"token":true}', "utf-8");
|
|
118
|
-
await fsPromises.writeFile(path.join(authDir, "notes.txt"), "keep", "utf-8");
|
|
119
|
-
await fsPromises.writeFile(path.join(authDir, "nested", "session-abc.json"), "keep", "utf-8");
|
|
120
|
-
|
|
121
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
122
|
-
expect(result).toBe(false);
|
|
123
|
-
expect(fs.existsSync(authDir)).toBe(true);
|
|
124
|
-
expect(fs.existsSync(path.join(authDir, "creds.json"))).toBe(true);
|
|
125
|
-
expect(fs.existsSync(path.join(authDir, "oauth.json"))).toBe(true);
|
|
126
|
-
expect(fs.existsSync(path.join(authDir, "notes.txt"))).toBe(true);
|
|
127
|
-
expect(fs.existsSync(path.join(authDir, "nested", "session-abc.json"))).toBe(true);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("does not delete through symlinked auth dirs inside the OpenClaw auth root", async () => {
|
|
131
|
-
const externalDir = await makeExternalCaseDir();
|
|
132
|
-
const authDir = path.join(fixtureRoot, "oauth", "whatsapp", `case-${caseId++}`);
|
|
133
|
-
await fsPromises.mkdir(path.dirname(authDir), { recursive: true });
|
|
134
|
-
await fsPromises.writeFile(path.join(externalDir, "creds.json"), "{}", "utf-8");
|
|
135
|
-
await fsPromises.writeFile(path.join(externalDir, "notes.txt"), "keep", "utf-8");
|
|
136
|
-
await fsPromises.symlink(externalDir, authDir, "dir");
|
|
137
|
-
|
|
138
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
139
|
-
expect(result).toBe(false);
|
|
140
|
-
expect(fs.existsSync(authDir)).toBe(true);
|
|
141
|
-
expect(fs.existsSync(path.join(externalDir, "creds.json"))).toBe(true);
|
|
142
|
-
expect(fs.existsSync(path.join(externalDir, "notes.txt"))).toBe(true);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("does not delete through intermediate symlinks inside the OpenClaw auth root", async () => {
|
|
146
|
-
const externalRoot = path.join(fixtureRoot, "external", `case-${caseId++}`);
|
|
147
|
-
const externalAuthDir = path.join(externalRoot, "default");
|
|
148
|
-
const linkedParent = path.join(fixtureRoot, "oauth", "whatsapp", `linked-${caseId++}`);
|
|
149
|
-
const authDir = path.join(linkedParent, "default");
|
|
150
|
-
await fsPromises.mkdir(externalAuthDir, { recursive: true });
|
|
151
|
-
await fsPromises.mkdir(path.dirname(linkedParent), { recursive: true });
|
|
152
|
-
await fsPromises.writeFile(path.join(externalAuthDir, "creds.json"), "{}", "utf-8");
|
|
153
|
-
await fsPromises.writeFile(path.join(externalAuthDir, "notes.txt"), "keep", "utf-8");
|
|
154
|
-
await fsPromises.symlink(externalRoot, linkedParent, "dir");
|
|
155
|
-
|
|
156
|
-
const result = await logoutWeb({ authDir, runtime: runtime as never });
|
|
157
|
-
expect(result).toBe(false);
|
|
158
|
-
expect(fs.existsSync(authDir)).toBe(true);
|
|
159
|
-
expect(fs.existsSync(path.join(externalAuthDir, "creds.json"))).toBe(true);
|
|
160
|
-
expect(fs.existsSync(path.join(externalAuthDir, "notes.txt"))).toBe(true);
|
|
161
|
-
});
|
|
162
|
-
});
|