mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
test (security/line): cover missing webhook auth startup paths
This commit is contained in:
103
extensions/line/src/channel.startup.test.ts
Normal file
103
extensions/line/src/channel.startup.test.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { linePlugin } from "./channel.js";
|
||||
import { setLineRuntime } from "./runtime.js";
|
||||
|
||||
function createRuntime() {
|
||||
const probeLineBot = vi.fn(async () => ({ ok: false }));
|
||||
const monitorLineProvider = vi.fn(async () => ({
|
||||
account: { accountId: "default" },
|
||||
handleWebhook: async () => {},
|
||||
stop: () => {},
|
||||
}));
|
||||
|
||||
const runtime = {
|
||||
channel: {
|
||||
line: {
|
||||
probeLineBot,
|
||||
monitorLineProvider,
|
||||
},
|
||||
},
|
||||
logging: {
|
||||
shouldLogVerbose: () => false,
|
||||
},
|
||||
} as unknown as PluginRuntime;
|
||||
|
||||
return { runtime, probeLineBot, monitorLineProvider };
|
||||
}
|
||||
|
||||
function createStartAccountCtx(params: {
|
||||
token: string;
|
||||
secret: string;
|
||||
runtime: unknown;
|
||||
}) {
|
||||
return {
|
||||
account: {
|
||||
accountId: "default",
|
||||
channelAccessToken: params.token,
|
||||
channelSecret: params.secret,
|
||||
config: {},
|
||||
},
|
||||
cfg: {} as OpenClawConfig,
|
||||
runtime: params.runtime,
|
||||
abortSignal: undefined,
|
||||
log: { info: vi.fn(), debug: vi.fn() },
|
||||
};
|
||||
}
|
||||
|
||||
describe("linePlugin gateway.startAccount", () => {
|
||||
it("fails startup when channel secret is missing", async () => {
|
||||
const { runtime, monitorLineProvider } = createRuntime();
|
||||
setLineRuntime(runtime);
|
||||
|
||||
await expect(
|
||||
linePlugin.gateway.startAccount(
|
||||
createStartAccountCtx({
|
||||
token: "token",
|
||||
secret: " ",
|
||||
runtime: {},
|
||||
}) as never,
|
||||
),
|
||||
).rejects.toThrow('LINE webhook mode requires a non-empty channel secret for account "default".');
|
||||
expect(monitorLineProvider).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("fails startup when channel access token is missing", async () => {
|
||||
const { runtime, monitorLineProvider } = createRuntime();
|
||||
setLineRuntime(runtime);
|
||||
|
||||
await expect(
|
||||
linePlugin.gateway.startAccount(
|
||||
createStartAccountCtx({
|
||||
token: " ",
|
||||
secret: "secret",
|
||||
runtime: {},
|
||||
}) as never,
|
||||
),
|
||||
).rejects.toThrow(
|
||||
'LINE webhook mode requires a non-empty channel access token for account "default".',
|
||||
);
|
||||
expect(monitorLineProvider).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("starts provider when token and secret are present", async () => {
|
||||
const { runtime, monitorLineProvider } = createRuntime();
|
||||
setLineRuntime(runtime);
|
||||
|
||||
await linePlugin.gateway.startAccount(
|
||||
createStartAccountCtx({
|
||||
token: "token",
|
||||
secret: "secret",
|
||||
runtime: {},
|
||||
}) as never,
|
||||
);
|
||||
|
||||
expect(monitorLineProvider).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
channelAccessToken: "token",
|
||||
channelSecret: "secret",
|
||||
accountId: "default",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
28
src/line/monitor.fail-closed.test.ts
Normal file
28
src/line/monitor.fail-closed.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { monitorLineProvider } from "./monitor.js";
|
||||
|
||||
describe("monitorLineProvider fail-closed webhook auth", () => {
|
||||
it("rejects startup when channel secret is missing", async () => {
|
||||
await expect(
|
||||
monitorLineProvider({
|
||||
channelAccessToken: "token",
|
||||
channelSecret: " ",
|
||||
config: {} as OpenClawConfig,
|
||||
runtime: {} as RuntimeEnv,
|
||||
}),
|
||||
).rejects.toThrow("LINE webhook mode requires a non-empty channel secret.");
|
||||
});
|
||||
|
||||
it("rejects startup when channel access token is missing", async () => {
|
||||
await expect(
|
||||
monitorLineProvider({
|
||||
channelAccessToken: " ",
|
||||
channelSecret: "secret",
|
||||
config: {} as OpenClawConfig,
|
||||
runtime: {} as RuntimeEnv,
|
||||
}),
|
||||
).rejects.toThrow("LINE webhook mode requires a non-empty channel access token.");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user