@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.
@@ -26,7 +26,7 @@ export type VerifySlackSignatureInput = {
26
26
  maxAgeSeconds?: number;
27
27
  /**
28
28
  * Override for the current Unix time in seconds. Mostly useful for tests;
29
- * defaults to `Math.floor(Date.now() / 1000)`.
29
+ * defaults to `Math.floor(DateTime.now().toSeconds())`.
30
30
  */
31
31
  now?: number;
32
32
  };
@@ -1 +1 @@
1
- {"version":3,"file":"slack.signature.d.ts","sourceRoot":"","sources":["../src/slack.signature.ts"],"names":[],"mappings":"AAGA,gGAAgG;AAChG,eAAO,MAAM,uCAAuC,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GACnC,mBAAmB,GACnB,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,qEAAqE;IACrE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,yBAAyB,KAAG,IAkDvE,CAAC"}
1
+ {"version":3,"file":"slack.signature.d.ts","sourceRoot":"","sources":["../src/slack.signature.ts"],"names":[],"mappings":"AAIA,gGAAgG;AAChG,eAAO,MAAM,uCAAuC,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GACnC,mBAAmB,GACnB,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,qEAAqE;IACrE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,yBAAyB,KAAG,IAkDvE,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { BinaryLike } from 'node:crypto';
2
+ import { Policy, PolicyEnvelope, PolicyResult } from '@maroonedsoftware/policies';
3
+ import { SlackConfig } from './slack.config.js';
4
+ /**
5
+ * Policy name under which {@link SlackSignaturePolicy} is registered. Use as the
6
+ * key when wiring your `PolicyRegistryMap`, and pass to `PolicyService.check`.
7
+ */
8
+ export declare const SLACK_SIGNATURE_POLICY: "slack.signature.valid";
9
+ /** Header carrying the request timestamp Slack signs into the HMAC. */
10
+ export declare const SLACK_REQUEST_TIMESTAMP_HEADER = "X-Slack-Request-Timestamp";
11
+ /** Header carrying the `v0=`-prefixed request signature. */
12
+ export declare const SLACK_SIGNATURE_HEADER = "X-Slack-Signature";
13
+ /**
14
+ * Configuration the {@link SlackSignaturePolicy} reads. A structural subset of
15
+ * {@link SlackConfig}, so a `SlackConfig` value satisfies it directly — e.g.
16
+ * `requireSignature<SlackSignatureOptions>('slack')` with the Slack config
17
+ * stored under that `AppConfig` key.
18
+ */
19
+ export type SlackSignatureOptions = Pick<SlackConfig, 'signingSecret' | 'signatureMaxAgeSeconds'>;
20
+ /**
21
+ * Context for {@link SlackSignaturePolicy}: the raw request bytes, a
22
+ * case-insensitive header accessor, and the {@link SlackSignatureOptions}.
23
+ *
24
+ * Structurally compatible with `@maroonedsoftware/koa`'s
25
+ * `SignaturePolicyContext<SlackSignatureOptions>`, so the koa `requireSignature`
26
+ * middleware can drive this policy without the slack package depending on koa —
27
+ * register `SlackSignaturePolicy` under the signature policy name and point the
28
+ * middleware at the `AppConfig` key holding the Slack config.
29
+ */
30
+ export interface SlackSignaturePolicyContext {
31
+ /** Raw, unparsed request body — exactly as Slack sent it (from `ctx.rawBody`). */
32
+ rawBody: BinaryLike;
33
+ /**
34
+ * Case-insensitive request header accessor (Koa's `ctx.get`); returns `''`
35
+ * when the header is absent.
36
+ */
37
+ getHeader: (name: string) => string;
38
+ /** Slack signing configuration. */
39
+ options: SlackSignatureOptions;
40
+ }
41
+ /**
42
+ * Policy form of {@link verifySlackSignature}: verifies a Slack request against
43
+ * the app signing secret using Slack's v0 scheme (HMAC over
44
+ * `v0:{timestamp}:{rawBody}`, `v0=`-prefixed, with timestamp replay
45
+ * protection).
46
+ *
47
+ * Delegates to {@link verifySlackSignature} so the crypto/timestamp logic has a
48
+ * single source of truth, but answers as a {@link PolicyResult} rather than
49
+ * throwing: allows on success, denies on failure with the helper's
50
+ * {@link SlackSignatureFailureReason} as the denial `reason` and its diagnostics
51
+ * (timestamps, window) on `internalDetails` — never the signing secret, never
52
+ * on the wire. The replay window is anchored to `envelope.now` so all policies
53
+ * in an evaluation share one clock.
54
+ *
55
+ * Registered by default under {@link SLACK_SIGNATURE_POLICY}.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * // Direct evaluation in a route handler:
60
+ * const result = await policyService.check(SLACK_SIGNATURE_POLICY, {
61
+ * rawBody: ctx.rawBody,
62
+ * getHeader: name => ctx.get(name),
63
+ * options: ctx.container.get(SlackConfig),
64
+ * });
65
+ * if (isPolicyResultDenied(result)) throw httpError(401);
66
+ * ```
67
+ */
68
+ export declare class SlackSignaturePolicy extends Policy<SlackSignaturePolicyContext> {
69
+ evaluate(context: SlackSignaturePolicyContext, envelope: PolicyEnvelope): Promise<PolicyResult>;
70
+ }
71
+ //# sourceMappingURL=slack.signature.policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.signature.policy.d.ts","sourceRoot":"","sources":["../src/slack.signature.policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAG,uBAAgC,CAAC;AAEvE,uEAAuE;AACvE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,WAAW,EAAE,eAAe,GAAG,wBAAwB,CAAC,CAAC;AAElG;;;;;;;;;GASG;AACH,MAAM,WAAW,2BAA2B;IAC1C,kFAAkF;IAClF,OAAO,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,mCAAmC;IACnC,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,oBAAqB,SAAQ,MAAM,CAAC,2BAA2B,CAAC;IACrE,QAAQ,CAAC,OAAO,EAAE,2BAA2B,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;CAwBtG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maroonedsoftware/slack",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "description": "Slack utilities for ServerKit.",
5
5
  "author": {
6
6
  "name": "Marooned Software",
@@ -31,11 +31,14 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@slack/web-api": "^7.16.0",
34
- "injectkit": "^1.4.1",
34
+ "injectkit": "^1.4.2",
35
35
  "@maroonedsoftware/errors": "1.7.0",
36
+ "@maroonedsoftware/policies": "0.5.0",
36
37
  "@maroonedsoftware/logger": "1.1.1"
37
38
  },
38
39
  "devDependencies": {
40
+ "@types/luxon": "^3.7.1",
41
+ "luxon": "^3.7.2",
39
42
  "@repo/config-eslint": "0.2.1",
40
43
  "@repo/config-typescript": "0.1.0"
41
44
  },