fix (security/line): fail closed when webhook auth is missing

This commit is contained in:
Vignesh Natarajan
2026-02-15 19:25:11 -08:00
parent d19b746928
commit beb77229c0
2 changed files with 26 additions and 6 deletions

View File

@@ -119,12 +119,13 @@ export const linePlugin: ChannelPlugin<ResolvedLineAccount> = {
},
};
},
isConfigured: (account) => Boolean(account.channelAccessToken?.trim()),
isConfigured: (account) =>
Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim()),
describeAccount: (account) => ({
accountId: account.accountId,
name: account.name,
enabled: account.enabled,
configured: Boolean(account.channelAccessToken?.trim()),
configured: Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim()),
tokenSource: account.tokenSource ?? undefined,
}),
resolveAllowFrom: ({ cfg, accountId }) =>
@@ -603,7 +604,7 @@ export const linePlugin: ChannelPlugin<ResolvedLineAccount> = {
probeAccount: async ({ account, timeoutMs }) =>
getLineRuntime().channel.line.probeLineBot(account.channelAccessToken, timeoutMs),
buildAccountSnapshot: ({ account, runtime, probe }) => {
const configured = Boolean(account.channelAccessToken?.trim());
const configured = Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim());
return {
accountId: account.accountId,
name: account.name,
@@ -626,6 +627,16 @@ export const linePlugin: ChannelPlugin<ResolvedLineAccount> = {
const account = ctx.account;
const token = account.channelAccessToken.trim();
const secret = account.channelSecret.trim();
if (!token) {
throw new Error(
`LINE webhook mode requires a non-empty channel access token for account "${account.accountId}".`,
);
}
if (!secret) {
throw new Error(
`LINE webhook mode requires a non-empty channel secret for account "${account.accountId}".`,
);
}
let lineBotLabel = "";
try {

View File

@@ -129,6 +129,15 @@ export async function monitorLineProvider(
webhookPath,
} = opts;
const resolvedAccountId = accountId ?? "default";
const token = channelAccessToken.trim();
const secret = channelSecret.trim();
if (!token) {
throw new Error("LINE webhook mode requires a non-empty channel access token.");
}
if (!secret) {
throw new Error("LINE webhook mode requires a non-empty channel secret.");
}
// Record starting state
recordChannelRuntimeState({
@@ -142,8 +151,8 @@ export async function monitorLineProvider(
// Create the bot
const bot = createLineBot({
channelAccessToken,
channelSecret,
channelAccessToken: token,
channelSecret: secret,
accountId,
runtime,
config,
@@ -281,7 +290,7 @@ export async function monitorLineProvider(
pluginId: "line",
accountId: resolvedAccountId,
log: (msg) => logVerbose(msg),
handler: createLineNodeWebhookHandler({ channelSecret, bot, runtime }),
handler: createLineNodeWebhookHandler({ channelSecret: secret, bot, runtime }),
});
logVerbose(`line: registered webhook handler at ${normalizedPath}`);