@maroonedsoftware/slack 1.8.2 → 1.9.0

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/README.md CHANGED
@@ -25,6 +25,7 @@ pnpm add @maroonedsoftware/slack
25
25
  | `SlackInteractionHandlerMap` | `Map<routingKey, SlackInteractionHandler>` — keys are `${type}:${identifier}`; see [interaction routing](#interaction-routing). |
26
26
  | `SlackError` | `ServerkitError` subclass for non-HTTP domain failures (signature mismatch, webhook POST failed, …). |
27
27
  | `verifySlackSignature(input)` | Pure helper that validates Slack's v0 HMAC scheme + replay window. No request/context coupling. |
28
+ | `SlackSignaturePolicy` | `@maroonedsoftware/policies` form of `verifySlackSignature` (registered under `SLACK_SIGNATURE_POLICY`). Delegates to the helper but answers as a `PolicyResult`, so it slots into ServerKit's policy pipeline. |
28
29
  | `interactionRouteKey(payload)` | Helper that produces the `SlackInteractionHandlerMap` key for a given payload. |
29
30
 
30
31
  ## Configuration
@@ -271,6 +272,29 @@ On any failure the helper throws `SlackError` with `internalDetails.reason` set
271
272
 
272
273
  For deterministic tests, pass `now` (Unix seconds) to override the clock.
273
274
 
275
+ ### As a policy
276
+
277
+ `SlackSignaturePolicy` is the same rule wrapped as a `@maroonedsoftware/policies` policy, so signature verification slots into ServerKit's policy pipeline alongside session/MFA policies. It delegates to `verifySlackSignature` (one source of truth) but returns a `PolicyResult` instead of throwing — denying with the same `SlackSignatureFailureReason` as the denial `reason`, and anchoring the replay window to the evaluation's `envelope.now`.
278
+
279
+ Register it in your `PolicyRegistryMap` and evaluate it via `PolicyService`:
280
+
281
+ ```ts
282
+ import { SlackSignaturePolicy, SLACK_SIGNATURE_POLICY, SlackConfig } from '@maroonedsoftware/slack';
283
+
284
+ // wiring
285
+ registry.set(SLACK_SIGNATURE_POLICY, SlackSignaturePolicy);
286
+
287
+ // in a route handler (ctx is a ServerKit Koa context)
288
+ const result = await ctx.container.get(PolicyService).check(SLACK_SIGNATURE_POLICY, {
289
+ rawBody: ctx.rawBody,
290
+ getHeader: name => ctx.get(name),
291
+ options: ctx.container.get(SlackConfig),
292
+ });
293
+ if (isPolicyResultDenied(result)) throw httpError(401).withInternalDetails(result.internalDetails ?? {});
294
+ ```
295
+
296
+ The context (`rawBody` + a case-insensitive `getHeader` + `options`) is structurally compatible with `@maroonedsoftware/koa`'s `SignaturePolicyContext<SlackSignatureOptions>`, so the koa `requireSignature` middleware can drive this policy when it's registered under the signature policy name — no koa dependency in this package.
297
+
274
298
  ## Limitations
275
299
 
276
300
  - v1 supports a single workspace via the bot token in `SlackConfig`. Multi-workspace OAuth install is out of scope.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './slack.config.js';
2
2
  export * from './slack.error.js';
3
3
  export * from './slack.signature.js';
4
+ export * from './slack.signature.policy.js';
4
5
  export * from './slack.event.handler.js';
5
6
  export * from './slack.command.handler.js';
6
7
  export * from './slack.interaction.handler.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC"}