experimental-ash 0.8.2 → 0.8.3
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.8.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e35a562: fix(slack): forward `webhookVerifier` credential to the underlying Slack adapter so Connex-issued credentials (`slackChannelCredentials` from `@vercel/connex/ash`) authenticate inbound webhooks via Vercel OIDC instead of HMAC.
|
|
8
|
+
|
|
9
|
+
Previously `SlackChannelCredentials` declared only `botToken` and `signingSecret`, and `slackChannel()` never passed `webhookVerifier` to `createSlackAdapter`. When Connex supplied `{ botToken, webhookVerifier }` and `SLACK_SIGNING_SECRET` was not set in the environment (the whole point of Connex), the adapter threw `ValidationError: signingSecret or webhookVerifier is required.` because the verifier was silently dropped on the ash side before reaching the adapter.
|
|
10
|
+
|
|
11
|
+
Concretely:
|
|
12
|
+
|
|
13
|
+
- `SlackChannelCredentials` now exposes `webhookVerifier?: SlackWebhookVerifier`. The verifier signature `(request: Request, body: string) => unknown | Promise<unknown>` is published as an ash-owned `SlackWebhookVerifier` type so we don't leak the third-party adapter type.
|
|
14
|
+
- `slackChannel()` forwards `webhookVerifier` to `createSlackAdapter` alongside `botToken` / `signingSecret` / `userName`.
|
|
15
|
+
- When a `webhookVerifier` is supplied, the resolver skips the `SLACK_SIGNING_SECRET` env-var fallback so Connex deployments don't accidentally pick up a stale env-var secret. An explicit `credentials.signingSecret` still wins if both are provided.
|
|
16
|
+
|
|
17
|
+
Public agent code is unchanged:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { slackChannelCredentials } from "@vercel/connex/ash";
|
|
21
|
+
import { slack } from "experimental-ash/channels/slack";
|
|
22
|
+
|
|
23
|
+
export default slack({
|
|
24
|
+
botName: "help-ash",
|
|
25
|
+
credentials: slackChannelCredentials("slack/help-ash"),
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
3
29
|
## 0.8.2
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -6,7 +6,7 @@ import { ASH_PACKAGE_NAME } from "#package-name.js";
|
|
|
6
6
|
let cachedPackageInfo;
|
|
7
7
|
// The package build stamps the published version into `dist` so bundled
|
|
8
8
|
// deployments can still report package metadata without resolving package.json.
|
|
9
|
-
const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.8.
|
|
9
|
+
const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.8.3";
|
|
10
10
|
const BUNDLED_FALLBACK_PACKAGE_VERSION_PLACEHOLDER = "__ASH_PACKAGE_VERSION_PLACEHOLDER__";
|
|
11
11
|
const WORKFLOW_MODULE_ALIASES = {
|
|
12
12
|
"workflow/api": "src/compiled/@workflow/core/runtime.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { slack, type SlackOptions } from "#public/channels/slack/slack.js";
|
|
2
|
-
export { slackChannel, type SlackApiHandle, type SlackApiResponse, type SlackChannel, type SlackChannelConfig, type SlackChannelEvents, type SlackChannelCredentials, type SlackChannelState, type SlackContext, type SlackInteractionAction, type SlackReceiveArgs, } from "#public/channels/slack/slackChannel.js";
|
|
2
|
+
export { slackChannel, type SlackApiHandle, type SlackApiResponse, type SlackChannel, type SlackChannelConfig, type SlackChannelEvents, type SlackChannelCredentials, type SlackChannelState, type SlackContext, type SlackInteractionAction, type SlackReceiveArgs, type SlackWebhookVerifier, } from "#public/channels/slack/slackChannel.js";
|
|
3
3
|
export { Actions, Button, Card, CardText, Divider, Fields, Image, LinkButton, Modal, RadioSelect, Section, Select, SelectOption, Table, TextInput, } from "#compiled/chat/index.js";
|
|
4
4
|
export type { AdapterPostableMessage, Attachment, Author, CardElement, FileUpload, Message, PostableMessage, SentMessage, Thread, } from "#compiled/chat/index.js";
|
|
@@ -28,9 +28,29 @@ export interface SlackChannelState {
|
|
|
28
28
|
serializedThread: SerializedThread | null;
|
|
29
29
|
teamId: string | null;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Verifies an inbound Slack webhook request. Returns when the request
|
|
33
|
+
* is authentic, throws otherwise. Used as an alternative to HMAC
|
|
34
|
+
* verification with `signingSecret` — for example, the Connex SDK
|
|
35
|
+
* supplies a verifier that authenticates Connex-forwarded webhooks
|
|
36
|
+
* with Vercel OIDC instead of Slack's signing secret.
|
|
37
|
+
*/
|
|
38
|
+
export type SlackWebhookVerifier = (request: Request, body: string) => unknown | Promise<unknown>;
|
|
31
39
|
export interface SlackChannelCredentials {
|
|
32
40
|
readonly botToken?: SlackBotToken;
|
|
41
|
+
/**
|
|
42
|
+
* Slack signing secret used to HMAC-verify inbound webhook requests.
|
|
43
|
+
* Falls back to `process.env.SLACK_SIGNING_SECRET` when neither this
|
|
44
|
+
* nor `webhookVerifier` is supplied.
|
|
45
|
+
*/
|
|
33
46
|
readonly signingSecret?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Custom inbound webhook verifier. When supplied, ash skips the
|
|
49
|
+
* `SLACK_SIGNING_SECRET` fallback and delegates verification to this
|
|
50
|
+
* function. Typically populated by integrations (e.g. Connex) that
|
|
51
|
+
* authenticate webhooks out-of-band.
|
|
52
|
+
*/
|
|
53
|
+
readonly webhookVerifier?: SlackWebhookVerifier;
|
|
34
54
|
}
|
|
35
55
|
export interface SlackReceiveArgs {
|
|
36
56
|
readonly channelId: string;
|
|
@@ -123,7 +123,12 @@ export function slackChannel(config = {}) {
|
|
|
123
123
|
return chatPromise;
|
|
124
124
|
const promise = (async () => {
|
|
125
125
|
const botToken = config.credentials?.botToken ?? process.env.SLACK_BOT_TOKEN;
|
|
126
|
-
const
|
|
126
|
+
const webhookVerifier = config.credentials?.webhookVerifier;
|
|
127
|
+
// Skip the SLACK_SIGNING_SECRET env-var fallback when a webhook
|
|
128
|
+
// verifier is supplied, so integrations like Connex don't need
|
|
129
|
+
// the signing secret set in the environment at all.
|
|
130
|
+
const signingSecret = config.credentials?.signingSecret ??
|
|
131
|
+
(webhookVerifier ? undefined : process.env.SLACK_SIGNING_SECRET);
|
|
127
132
|
if (!botToken) {
|
|
128
133
|
throw new Error("slackChannel requires a bot token. Pass credentials.botToken or set SLACK_BOT_TOKEN.");
|
|
129
134
|
}
|
|
@@ -135,6 +140,7 @@ export function slackChannel(config = {}) {
|
|
|
135
140
|
const slackAdapter = slackModule.createSlackAdapter({
|
|
136
141
|
botToken,
|
|
137
142
|
signingSecret,
|
|
143
|
+
webhookVerifier,
|
|
138
144
|
userName: config.botName,
|
|
139
145
|
});
|
|
140
146
|
const chat = new chatModule.Chat({
|