@maroonedsoftware/slack 1.8.1 → 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 +24 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6795 -21
- package/dist/index.js.map +1 -1
- package/dist/slack.signature.d.ts +1 -1
- package/dist/slack.signature.d.ts.map +1 -1
- package/dist/slack.signature.policy.d.ts +71 -0
- package/dist/slack.signature.policy.d.ts.map +1 -0
- package/package.json +10 -7
|
@@ -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(
|
|
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":"
|
|
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.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Slack utilities for ServerKit.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Marooned Software",
|
|
@@ -30,14 +30,17 @@
|
|
|
30
30
|
"dist/**"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@slack/web-api": "^7.
|
|
34
|
-
"injectkit": "^1.2
|
|
35
|
-
"@maroonedsoftware/
|
|
36
|
-
"@maroonedsoftware/
|
|
33
|
+
"@slack/web-api": "^7.16.0",
|
|
34
|
+
"injectkit": "^1.4.2",
|
|
35
|
+
"@maroonedsoftware/errors": "1.7.0",
|
|
36
|
+
"@maroonedsoftware/policies": "0.5.0",
|
|
37
|
+
"@maroonedsoftware/logger": "1.1.1"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"
|
|
40
|
+
"@types/luxon": "^3.7.1",
|
|
41
|
+
"luxon": "^3.7.2",
|
|
42
|
+
"@repo/config-eslint": "0.2.1",
|
|
43
|
+
"@repo/config-typescript": "0.1.0"
|
|
41
44
|
},
|
|
42
45
|
"scripts": {
|
|
43
46
|
"build": "tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration",
|