@cuylabs/channel-slack 0.3.0 → 0.5.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 +20 -12
- package/dist/bolt.d.ts +30 -1
- package/dist/bolt.js +163 -0
- package/dist/chunk-CMR6B76C.js +664 -0
- package/dist/{chunk-FX2JOVX5.js → chunk-IDVDMJ5U.js} +262 -1
- package/dist/diagnostics.d.ts +21 -104
- package/dist/diagnostics.js +21 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -1
- package/dist/inspect-BpY5JA0K.d.ts +128 -0
- package/dist/policy.d.ts +47 -1
- package/dist/policy.js +7 -1
- package/dist/setup.d.ts +1 -1
- package/dist/setup.js +1 -1
- package/docs/concepts/bolt-runtime.md +26 -0
- package/docs/concepts/message-policy.md +32 -0
- package/docs/reference/channel-slack-boundary.md +2 -2
- package/docs/reference/exports.md +12 -12
- package/package.json +1 -1
- package/dist/chunk-BODPT4I6.js +0 -322
|
@@ -200,6 +200,48 @@ async function inspectSlackTokenScopes(options = {}) {
|
|
|
200
200
|
errors
|
|
201
201
|
};
|
|
202
202
|
}
|
|
203
|
+
function normalizeSlackAuthTestIdentity(payload) {
|
|
204
|
+
const record = readRecord(payload);
|
|
205
|
+
const identity = {};
|
|
206
|
+
const url = readString(record?.url);
|
|
207
|
+
const team = readString(record?.team);
|
|
208
|
+
const teamId = readString(record?.team_id) ?? readString(record?.teamId);
|
|
209
|
+
const userId = readString(record?.user_id) ?? readString(record?.userId);
|
|
210
|
+
const botUserId = readString(record?.botUserId) ?? userId;
|
|
211
|
+
const botId = readString(record?.bot_id) ?? readString(record?.botId);
|
|
212
|
+
if (url) identity.url = url;
|
|
213
|
+
if (team) identity.team = team;
|
|
214
|
+
if (teamId) identity.teamId = teamId;
|
|
215
|
+
if (userId) identity.userId = userId;
|
|
216
|
+
if (botUserId) identity.botUserId = botUserId;
|
|
217
|
+
if (botId) identity.botId = botId;
|
|
218
|
+
return identity;
|
|
219
|
+
}
|
|
220
|
+
function compareSlackIdentity(identity, expected) {
|
|
221
|
+
const mismatches = [];
|
|
222
|
+
addIdentityMismatch(mismatches, {
|
|
223
|
+
actual: identity.teamId,
|
|
224
|
+
expected: expected.teamId,
|
|
225
|
+
field: "teamId",
|
|
226
|
+
label: "team"
|
|
227
|
+
});
|
|
228
|
+
addIdentityMismatch(mismatches, {
|
|
229
|
+
actual: identity.botUserId ?? identity.userId,
|
|
230
|
+
expected: expected.botUserId,
|
|
231
|
+
field: "botUserId",
|
|
232
|
+
label: "bot user"
|
|
233
|
+
});
|
|
234
|
+
addIdentityMismatch(mismatches, {
|
|
235
|
+
actual: identity.botId,
|
|
236
|
+
expected: expected.botId,
|
|
237
|
+
field: "botId",
|
|
238
|
+
label: "bot"
|
|
239
|
+
});
|
|
240
|
+
return mismatches;
|
|
241
|
+
}
|
|
242
|
+
function formatSlackIdentityMismatches(mismatches) {
|
|
243
|
+
return mismatches.map((mismatch) => mismatch.message);
|
|
244
|
+
}
|
|
203
245
|
async function resolveDiagnosticsClient(options) {
|
|
204
246
|
const explicitToken = normalizeToken(options.token);
|
|
205
247
|
if (options.client) {
|
|
@@ -398,8 +440,227 @@ function readBoolean(value) {
|
|
|
398
440
|
function elapsed(startedAt) {
|
|
399
441
|
return Date.now() - startedAt;
|
|
400
442
|
}
|
|
443
|
+
function addIdentityMismatch(mismatches, {
|
|
444
|
+
actual,
|
|
445
|
+
expected,
|
|
446
|
+
field,
|
|
447
|
+
label
|
|
448
|
+
}) {
|
|
449
|
+
if (!expected || expected === actual) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
mismatches.push({
|
|
453
|
+
actual,
|
|
454
|
+
expected,
|
|
455
|
+
field,
|
|
456
|
+
label,
|
|
457
|
+
message: `Expected Slack ${label} identity ${expected}, but the token resolved ${actual ?? "no value"}`
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/diagnostics/payload-debug.ts
|
|
462
|
+
function summarizeSlackPayloadDebug({
|
|
463
|
+
rawArgs,
|
|
464
|
+
slackActivity,
|
|
465
|
+
threadContext
|
|
466
|
+
}) {
|
|
467
|
+
const selectedRawArgs = selectSlackRawArgsForDebug(rawArgs);
|
|
468
|
+
return {
|
|
469
|
+
slackActivity: redactSlackDebugValue(slackActivity),
|
|
470
|
+
threadContext: redactSlackDebugValue(threadContext),
|
|
471
|
+
rawArgs: redactSlackDebugValue(selectedRawArgs),
|
|
472
|
+
rawArgsKeyPaths: collectJsonKeyPaths(selectedRawArgs),
|
|
473
|
+
rawArgsActionTokenPaths: findJsonKeyPaths(
|
|
474
|
+
selectedRawArgs,
|
|
475
|
+
(key) => ["action_token", "actiontoken"].includes(key.toLowerCase())
|
|
476
|
+
),
|
|
477
|
+
rawArgsTokenLikePaths: findJsonKeyPaths(
|
|
478
|
+
selectedRawArgs,
|
|
479
|
+
(key) => key.toLowerCase().includes("token")
|
|
480
|
+
)
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
function selectSlackRawArgsForDebug(rawArgs) {
|
|
484
|
+
const raw = rawArgs;
|
|
485
|
+
return {
|
|
486
|
+
body: selectSlackBodyForDebug(raw?.body),
|
|
487
|
+
payload: raw?.payload,
|
|
488
|
+
event: raw?.event,
|
|
489
|
+
message: raw?.message,
|
|
490
|
+
context: raw?.context
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
function selectSlackBodyForDebug(body) {
|
|
494
|
+
const raw = body;
|
|
495
|
+
return {
|
|
496
|
+
type: raw?.type,
|
|
497
|
+
team_id: raw?.team_id,
|
|
498
|
+
enterprise_id: raw?.enterprise_id,
|
|
499
|
+
api_app_id: raw?.api_app_id,
|
|
500
|
+
event: raw?.event,
|
|
501
|
+
event_id: raw?.event_id,
|
|
502
|
+
event_time: raw?.event_time,
|
|
503
|
+
event_context: raw?.event_context
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
function redactSlackDebugValue(value, depth = 0) {
|
|
507
|
+
if (value === null || value === void 0) {
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
510
|
+
if (typeof value === "string") {
|
|
511
|
+
return { type: "string", length: value.length };
|
|
512
|
+
}
|
|
513
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
514
|
+
return value;
|
|
515
|
+
}
|
|
516
|
+
if (Array.isArray(value)) {
|
|
517
|
+
return {
|
|
518
|
+
type: "array",
|
|
519
|
+
length: value.length,
|
|
520
|
+
sample: value.slice(0, 3).map((entry) => redactSlackDebugValue(entry, depth + 1))
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (typeof value !== "object") {
|
|
524
|
+
return { type: typeof value };
|
|
525
|
+
}
|
|
526
|
+
const entries = Object.entries(value);
|
|
527
|
+
if (depth >= 4) {
|
|
528
|
+
return {
|
|
529
|
+
type: "object",
|
|
530
|
+
keys: entries.map(([key]) => key)
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
return Object.fromEntries(
|
|
534
|
+
entries.map(([key, entry]) => [
|
|
535
|
+
key,
|
|
536
|
+
redactSlackDebugEntry(key, entry, depth)
|
|
537
|
+
])
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
function collectJsonKeyPaths(value) {
|
|
541
|
+
return collectJsonKeyPathsInternal(value, {
|
|
542
|
+
maxDepth: 7,
|
|
543
|
+
maxPaths: 300
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
function findJsonKeyPaths(value, predicate) {
|
|
547
|
+
return collectJsonKeyPathsInternal(value, {
|
|
548
|
+
maxDepth: 8,
|
|
549
|
+
maxPaths: 100,
|
|
550
|
+
predicate
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
function redactSlackDebugEntry(key, value, depth) {
|
|
554
|
+
const normalized = key.toLowerCase();
|
|
555
|
+
if (normalized.includes("token") || normalized.includes("secret") || normalized.includes("authorization") || normalized.includes("password")) {
|
|
556
|
+
return {
|
|
557
|
+
present: typeof value === "string" ? value.length > 0 : value !== void 0,
|
|
558
|
+
redacted: true
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
if (normalized === "text" || normalized === "markdown_text") {
|
|
562
|
+
return {
|
|
563
|
+
type: typeof value,
|
|
564
|
+
length: typeof value === "string" ? value.length : void 0,
|
|
565
|
+
redacted: true
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
if (typeof value === "string" && STRUCTURAL_SLACK_DEBUG_KEYS.has(normalized)) {
|
|
569
|
+
return value;
|
|
570
|
+
}
|
|
571
|
+
return redactSlackDebugValue(value, depth + 1);
|
|
572
|
+
}
|
|
573
|
+
var STRUCTURAL_SLACK_DEBUG_KEYS = /* @__PURE__ */ new Set([
|
|
574
|
+
"app_id",
|
|
575
|
+
"api_app_id",
|
|
576
|
+
"bot_id",
|
|
577
|
+
"botid",
|
|
578
|
+
"channel",
|
|
579
|
+
"channel_id",
|
|
580
|
+
"channelid",
|
|
581
|
+
"channel_type",
|
|
582
|
+
"channeltype",
|
|
583
|
+
"enterprise_id",
|
|
584
|
+
"enterpriseid",
|
|
585
|
+
"event_ts",
|
|
586
|
+
"eventts",
|
|
587
|
+
"messagets",
|
|
588
|
+
"team",
|
|
589
|
+
"team_id",
|
|
590
|
+
"teamid",
|
|
591
|
+
"thread_ts",
|
|
592
|
+
"threadts",
|
|
593
|
+
"ts",
|
|
594
|
+
"type",
|
|
595
|
+
"subtype",
|
|
596
|
+
"user",
|
|
597
|
+
"user_id",
|
|
598
|
+
"userid"
|
|
599
|
+
]);
|
|
600
|
+
function collectJsonKeyPathsInternal(value, {
|
|
601
|
+
maxDepth,
|
|
602
|
+
maxPaths,
|
|
603
|
+
predicate
|
|
604
|
+
}) {
|
|
605
|
+
const paths = [];
|
|
606
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
607
|
+
function visit(current, prefix, depth) {
|
|
608
|
+
if (paths.length >= maxPaths || current === null || current === void 0) {
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
if (typeof current !== "object") {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
if (seen.has(current)) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
seen.add(current);
|
|
618
|
+
if (Array.isArray(current)) {
|
|
619
|
+
if (current.length === 0) {
|
|
620
|
+
const path = `${prefix}[]`;
|
|
621
|
+
if (!predicate) {
|
|
622
|
+
paths.push(path);
|
|
623
|
+
}
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (depth >= maxDepth) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
for (const entry of current.slice(0, 3)) {
|
|
630
|
+
visit(entry, `${prefix}[]`, depth + 1);
|
|
631
|
+
}
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
if (depth >= maxDepth) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
for (const [key, entry] of Object.entries(
|
|
638
|
+
current
|
|
639
|
+
)) {
|
|
640
|
+
if (paths.length >= maxPaths) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
644
|
+
if (!predicate || predicate(key)) {
|
|
645
|
+
paths.push(path);
|
|
646
|
+
}
|
|
647
|
+
visit(entry, path, depth + 1);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
visit(value, "", 0);
|
|
651
|
+
return paths;
|
|
652
|
+
}
|
|
401
653
|
|
|
402
654
|
export {
|
|
403
655
|
inspectSlackConnection,
|
|
404
|
-
inspectSlackTokenScopes
|
|
656
|
+
inspectSlackTokenScopes,
|
|
657
|
+
normalizeSlackAuthTestIdentity,
|
|
658
|
+
compareSlackIdentity,
|
|
659
|
+
formatSlackIdentityMismatches,
|
|
660
|
+
summarizeSlackPayloadDebug,
|
|
661
|
+
selectSlackRawArgsForDebug,
|
|
662
|
+
selectSlackBodyForDebug,
|
|
663
|
+
redactSlackDebugValue,
|
|
664
|
+
collectJsonKeyPaths,
|
|
665
|
+
findJsonKeyPaths
|
|
405
666
|
};
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,105 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
interface SlackScopeInspectionMethodError {
|
|
22
|
-
method: SlackScopeInspectionMethod;
|
|
23
|
-
error: SlackApiInspectionError;
|
|
24
|
-
}
|
|
25
|
-
interface SlackScopeInspection {
|
|
26
|
-
ok: boolean;
|
|
27
|
-
scopes: string[];
|
|
28
|
-
source?: SlackScopeInspectionMethod;
|
|
29
|
-
errors: SlackScopeInspectionMethodError[];
|
|
30
|
-
}
|
|
31
|
-
interface SlackConnectionInspectionFinding {
|
|
32
|
-
severity: SlackConnectionInspectionFindingSeverity;
|
|
33
|
-
code: string;
|
|
34
|
-
message: string;
|
|
35
|
-
}
|
|
36
|
-
interface SlackConnectionAuthInfo {
|
|
37
|
-
ok: boolean;
|
|
38
|
-
url?: string;
|
|
39
|
-
team?: string;
|
|
40
|
-
teamId?: string;
|
|
41
|
-
user?: string;
|
|
42
|
-
userId?: string;
|
|
43
|
-
botId?: string;
|
|
44
|
-
enterpriseId?: string;
|
|
45
|
-
isEnterpriseInstall?: boolean;
|
|
46
|
-
}
|
|
47
|
-
interface SlackConnectionInspection {
|
|
48
|
-
ok: boolean;
|
|
49
|
-
tokenSource: SlackTokenSource;
|
|
50
|
-
elapsedMs: number;
|
|
51
|
-
auth?: SlackConnectionAuthInfo;
|
|
52
|
-
scopes?: SlackScopeInspection;
|
|
53
|
-
requiredScopes: string[];
|
|
54
|
-
optionalScopes: string[];
|
|
55
|
-
missingRequiredScopes: string[];
|
|
56
|
-
missingOptionalScopes: string[];
|
|
57
|
-
findings: SlackConnectionInspectionFinding[];
|
|
58
|
-
error?: SlackApiInspectionError;
|
|
59
|
-
}
|
|
60
|
-
interface InspectSlackTokenScopesOptions {
|
|
61
|
-
/**
|
|
62
|
-
* Slack bot or user OAuth token. When omitted, the injected client is used
|
|
63
|
-
* as-is and no token override is passed to Slack API calls.
|
|
64
|
-
*/
|
|
65
|
-
token?: string;
|
|
66
|
-
/** Inject a preconfigured Slack Web API client, useful for OAuth stores/tests. */
|
|
67
|
-
client?: SlackDiagnosticsClient;
|
|
68
|
-
/**
|
|
69
|
-
* Maximum time for each Slack API request in milliseconds. Set `0` to
|
|
70
|
-
* disable the local timeout wrapper.
|
|
71
|
-
*
|
|
72
|
-
* @default 2500
|
|
73
|
-
*/
|
|
74
|
-
requestTimeoutMs?: number;
|
|
75
|
-
/**
|
|
76
|
-
* Scope-bearing methods to try in order.
|
|
77
|
-
*
|
|
78
|
-
* @default ["auth.test", "auth.scopes", "apps.permissions.info"]
|
|
79
|
-
*/
|
|
80
|
-
methods?: readonly SlackScopeInspectionMethod[];
|
|
81
|
-
}
|
|
82
|
-
interface InspectSlackConnectionOptions extends Omit<InspectSlackTokenScopesOptions, "methods"> {
|
|
83
|
-
/**
|
|
84
|
-
* Slack OAuth scopes that must be present for this installation to be
|
|
85
|
-
* considered usable by the caller.
|
|
86
|
-
*/
|
|
87
|
-
requiredScopes?: readonly string[];
|
|
88
|
-
/**
|
|
89
|
-
* Slack OAuth scopes that are useful but not mandatory. Missing optional
|
|
90
|
-
* scopes are returned as warnings.
|
|
91
|
-
*/
|
|
92
|
-
optionalScopes?: readonly string[];
|
|
93
|
-
/**
|
|
94
|
-
* Whether to inspect token scopes after `auth.test` succeeds.
|
|
95
|
-
*
|
|
96
|
-
* @default true
|
|
97
|
-
*/
|
|
98
|
-
inspectScopes?: boolean;
|
|
99
|
-
/** Override the scope-inspection method order. */
|
|
100
|
-
scopeMethods?: readonly SlackScopeInspectionMethod[];
|
|
101
|
-
}
|
|
102
|
-
declare function inspectSlackConnection(options?: InspectSlackConnectionOptions): Promise<SlackConnectionInspection>;
|
|
103
|
-
declare function inspectSlackTokenScopes(options?: InspectSlackTokenScopesOptions): Promise<SlackScopeInspection>;
|
|
1
|
+
export { I as InspectSlackConnectionOptions, a as InspectSlackTokenScopesOptions, S as SlackApiInspectionError, b as SlackAuthTestIdentity, c as SlackConnectionInspection, d as SlackConnectionInspectionFinding, e as SlackConnectionInspectionFindingSeverity, f as SlackDiagnosticsClient, g as SlackIdentityExpectations, h as SlackIdentityMismatch, i as SlackScopeInspection, j as SlackScopeInspectionMethod, k as SlackScopeInspectionMethodError, l as SlackTokenSource, m as compareSlackIdentity, n as formatSlackIdentityMismatches, o as inspectSlackConnection, p as inspectSlackTokenScopes, q as normalizeSlackAuthTestIdentity } from './inspect-BpY5JA0K.js';
|
|
2
|
+
|
|
3
|
+
interface SlackPayloadDebugSummary {
|
|
4
|
+
rawArgs: unknown;
|
|
5
|
+
rawArgsActionTokenPaths: string[];
|
|
6
|
+
rawArgsKeyPaths: string[];
|
|
7
|
+
rawArgsTokenLikePaths: string[];
|
|
8
|
+
slackActivity: unknown;
|
|
9
|
+
threadContext: unknown;
|
|
10
|
+
}
|
|
11
|
+
declare function summarizeSlackPayloadDebug({ rawArgs, slackActivity, threadContext, }: {
|
|
12
|
+
rawArgs?: unknown;
|
|
13
|
+
slackActivity: unknown;
|
|
14
|
+
threadContext: unknown;
|
|
15
|
+
}): SlackPayloadDebugSummary;
|
|
16
|
+
declare function selectSlackRawArgsForDebug(rawArgs: unknown): unknown;
|
|
17
|
+
declare function selectSlackBodyForDebug(body: unknown): unknown;
|
|
18
|
+
declare function redactSlackDebugValue(value: unknown, depth?: number): unknown;
|
|
19
|
+
declare function collectJsonKeyPaths(value: unknown): string[];
|
|
20
|
+
declare function findJsonKeyPaths(value: unknown, predicate: (key: string) => boolean): string[];
|
|
104
21
|
|
|
105
|
-
export { type
|
|
22
|
+
export { type SlackPayloadDebugSummary, collectJsonKeyPaths, findJsonKeyPaths, redactSlackDebugValue, selectSlackBodyForDebug, selectSlackRawArgsForDebug, summarizeSlackPayloadDebug };
|
package/dist/diagnostics.js
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
+
collectJsonKeyPaths,
|
|
3
|
+
compareSlackIdentity,
|
|
4
|
+
findJsonKeyPaths,
|
|
5
|
+
formatSlackIdentityMismatches,
|
|
2
6
|
inspectSlackConnection,
|
|
3
|
-
inspectSlackTokenScopes
|
|
4
|
-
|
|
7
|
+
inspectSlackTokenScopes,
|
|
8
|
+
normalizeSlackAuthTestIdentity,
|
|
9
|
+
redactSlackDebugValue,
|
|
10
|
+
selectSlackBodyForDebug,
|
|
11
|
+
selectSlackRawArgsForDebug,
|
|
12
|
+
summarizeSlackPayloadDebug
|
|
13
|
+
} from "./chunk-IDVDMJ5U.js";
|
|
5
14
|
export {
|
|
15
|
+
collectJsonKeyPaths,
|
|
16
|
+
compareSlackIdentity,
|
|
17
|
+
findJsonKeyPaths,
|
|
18
|
+
formatSlackIdentityMismatches,
|
|
6
19
|
inspectSlackConnection,
|
|
7
|
-
inspectSlackTokenScopes
|
|
20
|
+
inspectSlackTokenScopes,
|
|
21
|
+
normalizeSlackAuthTestIdentity,
|
|
22
|
+
redactSlackDebugValue,
|
|
23
|
+
selectSlackBodyForDebug,
|
|
24
|
+
selectSlackRawArgsForDebug,
|
|
25
|
+
summarizeSlackPayloadDebug
|
|
8
26
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { S as SlackActivityInfo, a as SlackChannelType, b as SlackUserIdentity } from './activity-ByrD9Ftr.js';
|
|
2
2
|
export { ExtractSlackMessageTextOptions, RawSlackActionTokenPayload, RawSlackAppMentionPayload, RawSlackAssistantThreadPayload, RawSlackMessagePayload, SlackAmbientTurnContext, SlackApprovalRequest, SlackAssistantStatusUpdate, SlackAssistantSuggestedPrompt, SlackAssistantSuggestedPrompts, SlackAssistantTaskDisplayMode, SlackAssistantThreadContext, SlackAssistantUtilities, SlackAuthContext, SlackChatStreamStartArgs, SlackEventInteractiveRequestHandler, SlackHumanInputRequest, SlackInteractiveMessage, SlackInteractiveMessageRef, SlackInteractiveRequest, SlackInteractiveRequestBaseContext, SlackInteractiveRequestContext, SlackInteractiveRequestHandler, SlackInteractiveRequestKind, SlackInteractiveResponder, SlackMessageAuthorshipOptions, SlackMessageFormatter, SlackMessageFormattingOptions, SlackMessageTextPayload, SlackThreadStatusSetter, SlackTurnPreparation, SlackTurnRequestContext, currentSlackTurnContext, extractSlackActionToken, extractSlackAttachmentsText, extractSlackAuthContext, extractSlackBlocksText, extractSlackMessageText, extractSlackUserIdentity, formatSlackAttributedFollowUp, isProcessableMessage, markdownToSlackMrkdwn, parseSlackMentionActivity, parseSlackMessageActivity, resolveSlackChannelType, resolveSlackMessageFormatter, resolveThreadAwareSlackSessionId, runWithSlackTurnContext, stripLeadingMentions } from './core.js';
|
|
3
|
-
export { SlackAsyncMessagePolicyConfig, SlackAsyncMessagePolicyResolver, SlackChannelMessagePolicy, SlackMentionedThreadState, SlackMessagePolicyAcceptReason, SlackMessagePolicyAcceptedDecision, SlackMessagePolicyConfig, SlackMessagePolicyDecision, SlackMessagePolicyRejectReason, SlackMessagePolicyRejectedDecision, SlackMessagePolicyResolver, SlackMessagePolicyStateContext, SlackMessagePolicyStateStore, SlackSyncMessagePolicyStateStore, SlackThreadReplyPolicy, createAsyncSlackMessagePolicyResolver, createInMemorySlackMessagePolicyStateStore, createSlackMessagePolicyMessageKey, createSlackMessagePolicyResolver, createSlackMessagePolicyThreadKey, shouldRegisterSlackPassiveChannelMessages } from './policy.js';
|
|
3
|
+
export { PostgresSlackMessagePolicyPruneResult, PostgresSlackMessagePolicyStateStore, PostgresSlackMessagePolicyStateStoreOptions, SlackAsyncMessagePolicyConfig, SlackAsyncMessagePolicyResolver, SlackChannelMessagePolicy, SlackMentionedThreadState, SlackMessagePolicyAcceptReason, SlackMessagePolicyAcceptedDecision, SlackMessagePolicyConfig, SlackMessagePolicyDecision, SlackMessagePolicyPostgresClient, SlackMessagePolicyRejectReason, SlackMessagePolicyRejectedDecision, SlackMessagePolicyResolver, SlackMessagePolicyStateContext, SlackMessagePolicyStateStore, SlackSyncMessagePolicyStateStore, SlackThreadReplyPolicy, createAsyncSlackMessagePolicyResolver, createInMemorySlackMessagePolicyStateStore, createPostgresSlackMessagePolicyStateStore, createSlackMessagePolicyMessageKey, createSlackMessagePolicyResolver, createSlackMessagePolicyThreadKey, initializePostgresSlackMessagePolicyState, prunePostgresSlackMessagePolicyState, shouldRegisterSlackPassiveChannelMessages } from './policy.js';
|
|
4
4
|
export { L as Logger } from './logging-Bl3HfcC8.js';
|
package/dist/index.js
CHANGED
|
@@ -25,14 +25,18 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
createAsyncSlackMessagePolicyResolver,
|
|
27
27
|
createInMemorySlackMessagePolicyStateStore,
|
|
28
|
+
createPostgresSlackMessagePolicyStateStore,
|
|
28
29
|
createSlackMessagePolicyMessageKey,
|
|
29
30
|
createSlackMessagePolicyResolver,
|
|
30
31
|
createSlackMessagePolicyThreadKey,
|
|
32
|
+
initializePostgresSlackMessagePolicyState,
|
|
33
|
+
prunePostgresSlackMessagePolicyState,
|
|
31
34
|
shouldRegisterSlackPassiveChannelMessages
|
|
32
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-CMR6B76C.js";
|
|
33
36
|
export {
|
|
34
37
|
createAsyncSlackMessagePolicyResolver,
|
|
35
38
|
createInMemorySlackMessagePolicyStateStore,
|
|
39
|
+
createPostgresSlackMessagePolicyStateStore,
|
|
36
40
|
createSlackMessagePolicyMessageKey,
|
|
37
41
|
createSlackMessagePolicyResolver,
|
|
38
42
|
createSlackMessagePolicyThreadKey,
|
|
@@ -44,10 +48,12 @@ export {
|
|
|
44
48
|
extractSlackMessageText,
|
|
45
49
|
extractSlackUserIdentity,
|
|
46
50
|
formatSlackAttributedFollowUp,
|
|
51
|
+
initializePostgresSlackMessagePolicyState,
|
|
47
52
|
isProcessableMessage,
|
|
48
53
|
markdownToSlackMrkdwn,
|
|
49
54
|
parseSlackMentionActivity,
|
|
50
55
|
parseSlackMessageActivity,
|
|
56
|
+
prunePostgresSlackMessagePolicyState,
|
|
51
57
|
resolveSlackChannelType,
|
|
52
58
|
resolveSlackMessageFormatter,
|
|
53
59
|
resolveThreadAwareSlackSessionId,
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
type SlackScopeInspectionMethod = "auth.test" | "auth.scopes" | "apps.permissions.info";
|
|
2
|
+
type SlackConnectionInspectionFindingSeverity = "info" | "warning" | "error";
|
|
3
|
+
type SlackTokenSource = "provided" | "environment" | "client" | "none";
|
|
4
|
+
interface SlackDiagnosticsClient {
|
|
5
|
+
auth: {
|
|
6
|
+
test(args?: {
|
|
7
|
+
token?: string;
|
|
8
|
+
}): Promise<unknown>;
|
|
9
|
+
};
|
|
10
|
+
apiCall(method: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
interface SlackApiInspectionError {
|
|
13
|
+
message: string;
|
|
14
|
+
code?: string;
|
|
15
|
+
method?: string;
|
|
16
|
+
needed?: string;
|
|
17
|
+
providedScopes?: string[];
|
|
18
|
+
acceptedScopes?: string[];
|
|
19
|
+
statusCode?: number;
|
|
20
|
+
}
|
|
21
|
+
interface SlackScopeInspectionMethodError {
|
|
22
|
+
method: SlackScopeInspectionMethod;
|
|
23
|
+
error: SlackApiInspectionError;
|
|
24
|
+
}
|
|
25
|
+
interface SlackScopeInspection {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
scopes: string[];
|
|
28
|
+
source?: SlackScopeInspectionMethod;
|
|
29
|
+
errors: SlackScopeInspectionMethodError[];
|
|
30
|
+
}
|
|
31
|
+
interface SlackConnectionInspectionFinding {
|
|
32
|
+
severity: SlackConnectionInspectionFindingSeverity;
|
|
33
|
+
code: string;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
interface SlackConnectionAuthInfo {
|
|
37
|
+
ok: boolean;
|
|
38
|
+
url?: string;
|
|
39
|
+
team?: string;
|
|
40
|
+
teamId?: string;
|
|
41
|
+
user?: string;
|
|
42
|
+
userId?: string;
|
|
43
|
+
botId?: string;
|
|
44
|
+
enterpriseId?: string;
|
|
45
|
+
isEnterpriseInstall?: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface SlackAuthTestIdentity {
|
|
48
|
+
botId?: string;
|
|
49
|
+
botUserId?: string;
|
|
50
|
+
team?: string;
|
|
51
|
+
teamId?: string;
|
|
52
|
+
url?: string;
|
|
53
|
+
userId?: string;
|
|
54
|
+
}
|
|
55
|
+
interface SlackIdentityExpectations {
|
|
56
|
+
botId?: string;
|
|
57
|
+
botUserId?: string;
|
|
58
|
+
teamId?: string;
|
|
59
|
+
}
|
|
60
|
+
interface SlackIdentityMismatch {
|
|
61
|
+
actual?: string;
|
|
62
|
+
expected: string;
|
|
63
|
+
field: "botId" | "botUserId" | "teamId";
|
|
64
|
+
label: string;
|
|
65
|
+
message: string;
|
|
66
|
+
}
|
|
67
|
+
interface SlackConnectionInspection {
|
|
68
|
+
ok: boolean;
|
|
69
|
+
tokenSource: SlackTokenSource;
|
|
70
|
+
elapsedMs: number;
|
|
71
|
+
auth?: SlackConnectionAuthInfo;
|
|
72
|
+
scopes?: SlackScopeInspection;
|
|
73
|
+
requiredScopes: string[];
|
|
74
|
+
optionalScopes: string[];
|
|
75
|
+
missingRequiredScopes: string[];
|
|
76
|
+
missingOptionalScopes: string[];
|
|
77
|
+
findings: SlackConnectionInspectionFinding[];
|
|
78
|
+
error?: SlackApiInspectionError;
|
|
79
|
+
}
|
|
80
|
+
interface InspectSlackTokenScopesOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Slack bot or user OAuth token. When omitted, the injected client is used
|
|
83
|
+
* as-is and no token override is passed to Slack API calls.
|
|
84
|
+
*/
|
|
85
|
+
token?: string;
|
|
86
|
+
/** Inject a preconfigured Slack Web API client, useful for OAuth stores/tests. */
|
|
87
|
+
client?: SlackDiagnosticsClient;
|
|
88
|
+
/**
|
|
89
|
+
* Maximum time for each Slack API request in milliseconds. Set `0` to
|
|
90
|
+
* disable the local timeout wrapper.
|
|
91
|
+
*
|
|
92
|
+
* @default 2500
|
|
93
|
+
*/
|
|
94
|
+
requestTimeoutMs?: number;
|
|
95
|
+
/**
|
|
96
|
+
* Scope-bearing methods to try in order.
|
|
97
|
+
*
|
|
98
|
+
* @default ["auth.test", "auth.scopes", "apps.permissions.info"]
|
|
99
|
+
*/
|
|
100
|
+
methods?: readonly SlackScopeInspectionMethod[];
|
|
101
|
+
}
|
|
102
|
+
interface InspectSlackConnectionOptions extends Omit<InspectSlackTokenScopesOptions, "methods"> {
|
|
103
|
+
/**
|
|
104
|
+
* Slack OAuth scopes that must be present for this installation to be
|
|
105
|
+
* considered usable by the caller.
|
|
106
|
+
*/
|
|
107
|
+
requiredScopes?: readonly string[];
|
|
108
|
+
/**
|
|
109
|
+
* Slack OAuth scopes that are useful but not mandatory. Missing optional
|
|
110
|
+
* scopes are returned as warnings.
|
|
111
|
+
*/
|
|
112
|
+
optionalScopes?: readonly string[];
|
|
113
|
+
/**
|
|
114
|
+
* Whether to inspect token scopes after `auth.test` succeeds.
|
|
115
|
+
*
|
|
116
|
+
* @default true
|
|
117
|
+
*/
|
|
118
|
+
inspectScopes?: boolean;
|
|
119
|
+
/** Override the scope-inspection method order. */
|
|
120
|
+
scopeMethods?: readonly SlackScopeInspectionMethod[];
|
|
121
|
+
}
|
|
122
|
+
declare function inspectSlackConnection(options?: InspectSlackConnectionOptions): Promise<SlackConnectionInspection>;
|
|
123
|
+
declare function inspectSlackTokenScopes(options?: InspectSlackTokenScopesOptions): Promise<SlackScopeInspection>;
|
|
124
|
+
declare function normalizeSlackAuthTestIdentity(payload: unknown): SlackAuthTestIdentity;
|
|
125
|
+
declare function compareSlackIdentity(identity: SlackAuthTestIdentity, expected: SlackIdentityExpectations): SlackIdentityMismatch[];
|
|
126
|
+
declare function formatSlackIdentityMismatches(mismatches: readonly SlackIdentityMismatch[]): string[];
|
|
127
|
+
|
|
128
|
+
export { type InspectSlackConnectionOptions as I, type SlackApiInspectionError as S, type InspectSlackTokenScopesOptions as a, type SlackAuthTestIdentity as b, type SlackConnectionInspection as c, type SlackConnectionInspectionFinding as d, type SlackConnectionInspectionFindingSeverity as e, type SlackDiagnosticsClient as f, type SlackIdentityExpectations as g, type SlackIdentityMismatch as h, type SlackScopeInspection as i, type SlackScopeInspectionMethod as j, type SlackScopeInspectionMethodError as k, type SlackTokenSource as l, compareSlackIdentity as m, formatSlackIdentityMismatches as n, inspectSlackConnection as o, inspectSlackTokenScopes as p, normalizeSlackAuthTestIdentity as q };
|
package/dist/policy.d.ts
CHANGED
|
@@ -118,6 +118,52 @@ declare function createAsyncSlackMessagePolicyResolver(config?: SlackAsyncMessag
|
|
|
118
118
|
declare function createSlackMessagePolicyMessageKey(activity: SlackActivityInfo): string | undefined;
|
|
119
119
|
declare function createSlackMessagePolicyThreadKey(activity: SlackActivityInfo): string;
|
|
120
120
|
|
|
121
|
+
interface SlackMessagePolicyPostgresClient {
|
|
122
|
+
end?: () => Promise<void>;
|
|
123
|
+
query<T = unknown>(sql: string, values?: readonly unknown[]): Promise<{
|
|
124
|
+
rows: T[];
|
|
125
|
+
rowCount?: number | null;
|
|
126
|
+
}>;
|
|
127
|
+
}
|
|
128
|
+
interface PostgresSlackMessagePolicyStateStoreOptions {
|
|
129
|
+
acceptedMessageRetentionMs?: number;
|
|
130
|
+
acceptedMessagesTableName?: string;
|
|
131
|
+
client?: SlackMessagePolicyPostgresClient;
|
|
132
|
+
connectionString?: string;
|
|
133
|
+
ensureSchema?: boolean;
|
|
134
|
+
mentionedThreadRetentionMs?: number;
|
|
135
|
+
mentionedThreadsTableName?: string;
|
|
136
|
+
onPruneError?: (error: unknown) => void;
|
|
137
|
+
pruneBatchSize?: number;
|
|
138
|
+
pruneIntervalMs?: number;
|
|
139
|
+
schema?: string;
|
|
140
|
+
}
|
|
141
|
+
interface PostgresSlackMessagePolicyStateStore extends SlackMessagePolicyStateStore {
|
|
142
|
+
close(): Promise<void>;
|
|
143
|
+
prune(): Promise<PostgresSlackMessagePolicyPruneResult>;
|
|
144
|
+
}
|
|
145
|
+
interface PostgresSlackMessagePolicyPruneResult {
|
|
146
|
+
acceptedMessagesDeleted: number;
|
|
147
|
+
mentionedThreadsDeleted: number;
|
|
148
|
+
}
|
|
149
|
+
declare function createPostgresSlackMessagePolicyStateStore({ acceptedMessageRetentionMs, acceptedMessagesTableName, client, connectionString, ensureSchema, mentionedThreadRetentionMs, mentionedThreadsTableName, onPruneError, pruneBatchSize, pruneIntervalMs, schema, }: PostgresSlackMessagePolicyStateStoreOptions): PostgresSlackMessagePolicyStateStore;
|
|
150
|
+
declare function initializePostgresSlackMessagePolicyState({ acceptedMessagesTableName, client, ensureSchema, mentionedThreadsTableName, schema, }: {
|
|
151
|
+
acceptedMessagesTableName?: string;
|
|
152
|
+
client: SlackMessagePolicyPostgresClient;
|
|
153
|
+
ensureSchema?: boolean;
|
|
154
|
+
mentionedThreadsTableName?: string;
|
|
155
|
+
schema?: string;
|
|
156
|
+
}): Promise<void>;
|
|
157
|
+
declare function prunePostgresSlackMessagePolicyState({ acceptedMessageRetentionMs, acceptedMessagesTableName, client, mentionedThreadRetentionMs, mentionedThreadsTableName, pruneBatchSize, schema, }: {
|
|
158
|
+
acceptedMessageRetentionMs?: number;
|
|
159
|
+
acceptedMessagesTableName?: string;
|
|
160
|
+
client: SlackMessagePolicyPostgresClient;
|
|
161
|
+
mentionedThreadRetentionMs?: number;
|
|
162
|
+
mentionedThreadsTableName?: string;
|
|
163
|
+
pruneBatchSize?: number;
|
|
164
|
+
schema?: string;
|
|
165
|
+
}): Promise<PostgresSlackMessagePolicyPruneResult>;
|
|
166
|
+
|
|
121
167
|
declare function shouldRegisterSlackPassiveChannelMessages(config?: SlackMessagePolicyConfig): boolean;
|
|
122
168
|
|
|
123
169
|
declare function createSlackMessagePolicyResolver(config?: SlackMessagePolicyConfig): SlackMessagePolicyResolver;
|
|
@@ -127,4 +173,4 @@ declare function createInMemorySlackMessagePolicyStateStore({ maxAcceptedMessage
|
|
|
127
173
|
maxMentionedThreads?: number;
|
|
128
174
|
}): SlackSyncMessagePolicyStateStore;
|
|
129
175
|
|
|
130
|
-
export { type SlackAsyncMessagePolicyConfig, type SlackAsyncMessagePolicyResolver, type SlackChannelMessagePolicy, type SlackMentionedThreadState, type SlackMessagePolicyAcceptReason, type SlackMessagePolicyAcceptedDecision, type SlackMessagePolicyConfig, type SlackMessagePolicyDecision, type SlackMessagePolicyRejectReason, type SlackMessagePolicyRejectedDecision, type SlackMessagePolicyResolver, type SlackMessagePolicyStateContext, type SlackMessagePolicyStateStore, type SlackSyncMessagePolicyStateStore, type SlackThreadReplyPolicy, createAsyncSlackMessagePolicyResolver, createInMemorySlackMessagePolicyStateStore, createSlackMessagePolicyMessageKey, createSlackMessagePolicyResolver, createSlackMessagePolicyThreadKey, shouldRegisterSlackPassiveChannelMessages };
|
|
176
|
+
export { type PostgresSlackMessagePolicyPruneResult, type PostgresSlackMessagePolicyStateStore, type PostgresSlackMessagePolicyStateStoreOptions, type SlackAsyncMessagePolicyConfig, type SlackAsyncMessagePolicyResolver, type SlackChannelMessagePolicy, type SlackMentionedThreadState, type SlackMessagePolicyAcceptReason, type SlackMessagePolicyAcceptedDecision, type SlackMessagePolicyConfig, type SlackMessagePolicyDecision, type SlackMessagePolicyPostgresClient, type SlackMessagePolicyRejectReason, type SlackMessagePolicyRejectedDecision, type SlackMessagePolicyResolver, type SlackMessagePolicyStateContext, type SlackMessagePolicyStateStore, type SlackSyncMessagePolicyStateStore, type SlackThreadReplyPolicy, createAsyncSlackMessagePolicyResolver, createInMemorySlackMessagePolicyStateStore, createPostgresSlackMessagePolicyStateStore, createSlackMessagePolicyMessageKey, createSlackMessagePolicyResolver, createSlackMessagePolicyThreadKey, initializePostgresSlackMessagePolicyState, prunePostgresSlackMessagePolicyState, shouldRegisterSlackPassiveChannelMessages };
|