Skip to content

chore: move to chat sdk#2115

Open
thibaultleouay wants to merge 1 commit intomainfrom
chat-sdk-try
Open

chore: move to chat sdk#2115
thibaultleouay wants to merge 1 commit intomainfrom
chat-sdk-try

Conversation

@thibaultleouay
Copy link
Copy Markdown
Member

No description provided.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openstatus-dashboard Ready Ready Preview, Comment Apr 23, 2026 1:31pm
openstatus-status-page Ready Ready Preview, Comment Apr 23, 2026 1:31pm
openstatus-web Ready Ready Preview, Comment Apr 23, 2026 1:31pm

Request Review

return c.json({ ok: true });
}

async function processEvent(body: SlackEvent) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now to event.ts

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 28 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/server/src/routes/slack/actions.ts">

<violation number="1" location="apps/server/src/routes/slack/actions.ts:362">
P2: The cancel action no longer verifies the requesting user matches the pending action owner. That allows any user to cancel another user’s pending action.</violation>
</file>

<file name="apps/server/src/routes/slack/confirmation-store.ts">

<violation number="1" location="apps/server/src/routes/slack/confirmation-store.ts:149">
P2: Refresh the thread mapping TTL when updating the action to keep `findByThread` working for the full TTL window.</violation>
</file>

<file name="apps/server/package.json">

<violation number="1" location="apps/server/package.json:18">
P2: Pin this dependency to an exact version instead of a caret range to align with repo versioning conventions.

(Based on your team's feedback about pinning dependency versions instead of using ranges.) [FEEDBACK_USED]</violation>
</file>

<file name="apps/server/src/routes/slack/index.ts">

<violation number="1" location="apps/server/src/routes/slack/index.ts:129">
P0: The `/webhooks` handler processes `app_uninstalled` and `tokens_revoked` events and deletes database records without verifying the Slack request signature. The old code had `verifySlackSignature` middleware; the new code removes it entirely. An attacker can forge a webhook to delete any workspace's Slack integration.

Verify the request signature (using `SLACK_SIGNING_SECRET` and the `X-Slack-Signature` / `X-Slack-Request-Timestamp` headers) before acting on the parsed body, or move this cleanup logic after the SDK's own verification step.</violation>

<violation number="2" location="apps/server/src/routes/slack/index.ts:161">
P1: The `slackAdapter` is created without `signingSecret` — only `clientId` and `clientSecret` are passed. Without the signing secret, `bot.webhooks.slack()` cannot verify Slack's request signatures. Pass `signingSecret: env.SLACK_SIGNING_SECRET` to `createSlackAdapter` so the SDK can authenticate incoming webhooks.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

}
});

slack.post("/webhooks", async (c) => {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: The /webhooks handler processes app_uninstalled and tokens_revoked events and deletes database records without verifying the Slack request signature. The old code had verifySlackSignature middleware; the new code removes it entirely. An attacker can forge a webhook to delete any workspace's Slack integration.

Verify the request signature (using SLACK_SIGNING_SECRET and the X-Slack-Signature / X-Slack-Request-Timestamp headers) before acting on the parsed body, or move this cleanup logic after the SDK's own verification step.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/src/routes/slack/index.ts, line 129:

<comment>The `/webhooks` handler processes `app_uninstalled` and `tokens_revoked` events and deletes database records without verifying the Slack request signature. The old code had `verifySlackSignature` middleware; the new code removes it entirely. An attacker can forge a webhook to delete any workspace's Slack integration.

Verify the request signature (using `SLACK_SIGNING_SECRET` and the `X-Slack-Signature` / `X-Slack-Request-Timestamp` headers) before acting on the parsed body, or move this cleanup logic after the SDK's own verification step.</comment>

<file context>
@@ -1,30 +1,165 @@
+  }
+});
+
+slack.post("/webhooks", async (c) => {
+  const cloned = c.req.raw.clone();
+  try {
</file context>
Fix with Cubic

// body parse failed — let the SDK handle it
}

const response = await bot.webhooks.slack(c.req.raw);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The slackAdapter is created without signingSecret — only clientId and clientSecret are passed. Without the signing secret, bot.webhooks.slack() cannot verify Slack's request signatures. Pass signingSecret: env.SLACK_SIGNING_SECRET to createSlackAdapter so the SDK can authenticate incoming webhooks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/src/routes/slack/index.ts, line 161:

<comment>The `slackAdapter` is created without `signingSecret` — only `clientId` and `clientSecret` are passed. Without the signing secret, `bot.webhooks.slack()` cannot verify Slack's request signatures. Pass `signingSecret: env.SLACK_SIGNING_SECRET` to `createSlackAdapter` so the SDK can authenticate incoming webhooks.</comment>

<file context>
@@ -1,30 +1,165 @@
+    // body parse failed — let the SDK handle it
+  }
+
+  const response = await bot.webhooks.slack(c.req.raw);
+  return response;
+});
</file context>
Fix with Cubic

Comment on lines +362 to +368
bot.onAction("cancel", async (event) => {
const actionId = event.value;
if (!actionId) return;
const consumed = await consume(actionId);
if (!consumed) return;
await editMessage(event.adapter, event.threadId, event.messageId, ":no_entry_sign: Cancelled.");
});
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The cancel action no longer verifies the requesting user matches the pending action owner. That allows any user to cancel another user’s pending action.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/src/routes/slack/actions.ts, line 362:

<comment>The cancel action no longer verifies the requesting user matches the pending action owner. That allows any user to cancel another user’s pending action.</comment>

<file context>
@@ -485,13 +351,19 @@ async function executeAction(
+export function registerActionHandlers() {
+  bot.onAction("approve", (event) => handleApproval(event, false));
+  bot.onAction("approve_notify", (event) => handleApproval(event, true));
+  bot.onAction("cancel", async (event) => {
+    const actionId = event.value;
+    if (!actionId) return;
</file context>
Suggested change
bot.onAction("cancel", async (event) => {
const actionId = event.value;
if (!actionId) return;
const consumed = await consume(actionId);
if (!consumed) return;
await editMessage(event.adapter, event.threadId, event.messageId, ":no_entry_sign: Cancelled.");
});
bot.onAction("cancel", async (event) => {
const actionId = event.value;
if (!actionId) return;
const pending = await get(actionId);
if (!pending) return;
if (pending.userId !== event.user.userId) {
if (event.thread) {
await event.thread.postEphemeral(
event.user,
"Only the person who initiated this action can approve or cancel it.",
{ fallbackToDM: false },
);
}
return;
}
const consumed = await consume(actionId);
if (!consumed) return;
await editMessage(event.adapter, event.threadId, event.messageId, ":no_entry_sign: Cancelled.");
});
Fix with Cubic

Comment on lines +149 to +151
await redis.set(`${ACTION_PREFIX}${actionId}`, JSON.stringify(existing), {
ex: TTL_SECONDS,
});
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Refresh the thread mapping TTL when updating the action to keep findByThread working for the full TTL window.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/src/routes/slack/confirmation-store.ts, line 149:

<comment>Refresh the thread mapping TTL when updating the action to keep `findByThread` working for the full TTL window.</comment>

<file context>
@@ -114,6 +118,39 @@ export async function store(
+
+  existing.messageTs = messageTs;
+
+  await redis.set(`${ACTION_PREFIX}${actionId}`, JSON.stringify(existing), {
+    ex: TTL_SECONDS,
+  });
</file context>
Suggested change
await redis.set(`${ACTION_PREFIX}${actionId}`, JSON.stringify(existing), {
ex: TTL_SECONDS,
});
await Promise.all([
redis.set(`${ACTION_PREFIX}${actionId}`, JSON.stringify(existing), {
ex: TTL_SECONDS,
}),
redis.expire(`${THREAD_PREFIX}${existing.threadTs}`, TTL_SECONDS),
]);
Fix with Cubic

Comment thread apps/server/package.json
"@ai-sdk/anthropic": "1.2.0",
"@bufbuild/protobuf": "2.10.2",
"@bufbuild/protovalidate": "^1.1.1",
"@chat-adapter/slack": "^4.26.0",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Pin this dependency to an exact version instead of a caret range to align with repo versioning conventions.

(Based on your team's feedback about pinning dependency versions instead of using ranges.)

View Feedback

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/package.json, line 18:

<comment>Pin this dependency to an exact version instead of a caret range to align with repo versioning conventions.

(Based on your team's feedback about pinning dependency versions instead of using ranges.) </comment>

<file context>
@@ -12,8 +12,11 @@
+    "@ai-sdk/anthropic": "1.2.0",
     "@bufbuild/protobuf": "2.10.2",
     "@bufbuild/protovalidate": "^1.1.1",
+    "@chat-adapter/slack": "^4.26.0",
+    "@chat-adapter/state-ioredis": "^4.26.0",
     "@connectrpc/connect": "2.1.1",
</file context>
Suggested change
"@chat-adapter/slack": "^4.26.0",
"@chat-adapter/slack": "4.26.0",
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant