agent-messenger 1.10.2 β 1.10.4
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/.claude-plugin/plugin.json +1 -1
- package/README.md +33 -27
- package/dist/package.json +1 -1
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/auth.js +19 -1
- package/dist/src/platforms/slack/commands/auth.js.map +1 -1
- package/dist/src/platforms/slack/ensure-auth.d.ts +6 -0
- package/dist/src/platforms/slack/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/ensure-auth.js +45 -1
- package/dist/src/platforms/slack/ensure-auth.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts +4 -0
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +123 -1
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/package.json +1 -1
- package/skills/agent-discord/SKILL.md +77 -1
- package/skills/agent-discord/references/authentication.md +2 -7
- package/skills/agent-discordbot/SKILL.md +78 -1
- package/skills/agent-slack/SKILL.md +77 -1
- package/skills/agent-slack/references/authentication.md +2 -10
- package/skills/agent-slackbot/SKILL.md +78 -1
- package/skills/agent-teams/SKILL.md +77 -1
- package/skills/agent-teams/references/authentication.md +2 -7
- package/src/platforms/slack/commands/auth.ts +22 -1
- package/src/platforms/slack/ensure-auth.test.ts +125 -1
- package/src/platforms/slack/ensure-auth.ts +49 -2
- package/src/platforms/slack/token-extractor.test.ts +184 -0
- package/src/platforms/slack/token-extractor.ts +129 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-messenger",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.4",
|
|
4
4
|
"description": "Messaging platform interaction skills for AI agents. Interact with Slack, Discord, and Microsoft Teams - send messages, read channels, manage reactions, upload files, and more through simple CLI interfaces.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "devxoul",
|
package/README.md
CHANGED
|
@@ -10,38 +10,40 @@ A unified, agent-friendly CLI for messaging platforms. Zero-config credential ex
|
|
|
10
10
|
|
|
11
11
|
## Table of Contents
|
|
12
12
|
|
|
13
|
-
- [Why Agent Messenger?](
|
|
14
|
-
- [Installation](
|
|
15
|
-
- [Agent Skills](
|
|
13
|
+
- [Why Agent Messenger?](#why-agent-messenger)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Agent Skills](#agent-skills)
|
|
16
16
|
- [SkillPad](#skillpad)
|
|
17
17
|
- [Skills CLI](#skills-cli)
|
|
18
18
|
- [Claude Code Plugin](#claude-code-plugin)
|
|
19
19
|
- [OpenCode Plugin](#opencode-plugin)
|
|
20
|
-
- [Quick Start](
|
|
21
|
-
- [Supported Platforms](
|
|
22
|
-
- [Platform Guides](
|
|
23
|
-
- [Use Cases](
|
|
20
|
+
- [Quick Start](#quick-start)
|
|
21
|
+
- [Supported Platforms](#supported-platforms)
|
|
22
|
+
- [Platform Guides](#platform-guides)
|
|
23
|
+
- [Use Cases](#use-cases)
|
|
24
24
|
- [Gathering Context](#gathering-context)
|
|
25
25
|
- [Communicating & Reporting](#communicating--reporting)
|
|
26
26
|
- [Automation & Pipelines](#automation--pipelines)
|
|
27
27
|
- [...and More](#and-more)
|
|
28
|
-
- [Philosophy](
|
|
29
|
-
- [Contributing](
|
|
30
|
-
- [
|
|
28
|
+
- [Philosophy](#philosophy)
|
|
29
|
+
- [Contributing](#contributing)
|
|
30
|
+
- [Thanks](#thanks)
|
|
31
|
+
- [License](#license)
|
|
31
32
|
|
|
32
|
-
##
|
|
33
|
+
## Why Agent Messenger?
|
|
33
34
|
|
|
34
35
|
Messaging platforms only offer Bot tokens for API accessβyour AI agent can never act **as you**. Agent Messenger extracts user credentials directly from your installed desktop apps, letting your agent operate on your behalf. Bot tokens are fully supported too for server-side and CI/CD use cases.
|
|
35
36
|
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
37
|
+
- **Act as yourself, not a bot** β Extracted user tokens let your agent operate on your behalf
|
|
38
|
+
- **No API keys needed** β Automatically extracts credentials from your installed desktop apps
|
|
39
|
+
- **Zero setup** β Credentials are auto-extracted on first command. No manual auth step required
|
|
40
|
+
- **One interface, multiple platforms** β Learn once, use everywhere (Slack, Discord, Teams)
|
|
41
|
+
- **AI-agent friendly** β JSON output by default, perfect for LLM tool use
|
|
42
|
+
- **Agent memory** β Remembers workspace IDs, channel names, and preferences across sessions
|
|
43
|
+
- **Human friendly too** β Add `--pretty` for readable output
|
|
44
|
+
- **Token efficient** β CLI, not MCP. Load only what you need. ([Why not MCP?](#philosophy))
|
|
43
45
|
|
|
44
|
-
##
|
|
46
|
+
## Installation
|
|
45
47
|
|
|
46
48
|
```bash
|
|
47
49
|
npm install -g agent-messenger
|
|
@@ -56,7 +58,7 @@ This installs:
|
|
|
56
58
|
- `agent-discordbot` β Discord Bot CLI (bot token, for server-side/CI/CD)
|
|
57
59
|
- `agent-teams` β Microsoft Teams CLI
|
|
58
60
|
|
|
59
|
-
##
|
|
61
|
+
## Agent Skills
|
|
60
62
|
|
|
61
63
|
Agent Messenger includes [Agent Skills](https://agentskills.io/) that teach your AI agent how to use these CLIs effectively. Five skills are available:
|
|
62
64
|
|
|
@@ -106,7 +108,7 @@ Add to your `opencode.jsonc`:
|
|
|
106
108
|
}
|
|
107
109
|
```
|
|
108
110
|
|
|
109
|
-
##
|
|
111
|
+
## Quick Start
|
|
110
112
|
|
|
111
113
|
Get up and running in 30 seconds:
|
|
112
114
|
|
|
@@ -120,7 +122,7 @@ agent-slack message send general "Hello from the CLI!"
|
|
|
120
122
|
|
|
121
123
|
That's it. Credentials are extracted automatically from your Slack desktop app on first run. No OAuth flows. No API tokens. No configuration files.
|
|
122
124
|
|
|
123
|
-
##
|
|
125
|
+
## Supported Platforms
|
|
124
126
|
|
|
125
127
|
| Feature | Slack | Discord | Teams |
|
|
126
128
|
|---------|:-----:|:-------:|:-----:|
|
|
@@ -142,7 +144,7 @@ That's it. Credentials are extracted automatically from your Slack desktop app o
|
|
|
142
144
|
|
|
143
145
|
> β οΈ **Teams tokens expire in 60-90 minutes.** Re-run `agent-teams auth extract` to refresh. See [Teams Guide](skills/agent-teams/SKILL.md) for details.
|
|
144
146
|
|
|
145
|
-
##
|
|
147
|
+
## Platform Guides
|
|
146
148
|
|
|
147
149
|
- **[Slack Guide](https://agent-messenger.dev/docs/integrations/slack)** β Full command reference for Slack
|
|
148
150
|
- **[Slack Bot Guide](https://agent-messenger.dev/docs/integrations/slackbot)** β Bot token integration for server-side and CI/CD
|
|
@@ -150,7 +152,7 @@ That's it. Credentials are extracted automatically from your Slack desktop app o
|
|
|
150
152
|
- **[Discord Bot Guide](https://agent-messenger.dev/docs/integrations/discordbot)** β Bot token integration for server-side and CI/CD
|
|
151
153
|
- **[Teams Guide](https://agent-messenger.dev/docs/integrations/teams)** β Full command reference for Microsoft Teams
|
|
152
154
|
|
|
153
|
-
##
|
|
155
|
+
## Use Cases
|
|
154
156
|
|
|
155
157
|
### Gathering Context
|
|
156
158
|
|
|
@@ -197,7 +199,7 @@ Wire messaging into your CI, scripts, or agent workflows.
|
|
|
197
199
|
### ...and More
|
|
198
200
|
|
|
199
201
|
These are just starting points. Your agent has full read/write access to Slack, Discord, and Teams β anything you'd do manually in a chat app, it can handle for you. If you build something cool with Agent Messenger, [let me know](https://x.com/devxoul)!
|
|
200
|
-
##
|
|
202
|
+
## Philosophy
|
|
201
203
|
|
|
202
204
|
**Why not MCP?** MCP servers expose all tools at once, bloating context and confusing agents. **[Agent Skills](https://agentskills.io/) + agent-friendly CLI** offer a better approachβload what you need, when you need it. Fewer tokens, cleaner context, better output.
|
|
203
205
|
|
|
@@ -205,7 +207,7 @@ These are just starting points. Your agent has full read/write access to Slack,
|
|
|
205
207
|
|
|
206
208
|
Inspired by [agent-browser](https://github.com/vercel-labs/agent-browser) from Vercel Labs.
|
|
207
209
|
|
|
208
|
-
##
|
|
210
|
+
## Contributing
|
|
209
211
|
|
|
210
212
|
```bash
|
|
211
213
|
bun install # Install dependencies
|
|
@@ -216,6 +218,10 @@ bun lint # Lint
|
|
|
216
218
|
bun run build # Build
|
|
217
219
|
```
|
|
218
220
|
|
|
219
|
-
##
|
|
221
|
+
## Thanks
|
|
222
|
+
|
|
223
|
+
- [@goden-park](https://github.com/goden-park)
|
|
224
|
+
|
|
225
|
+
## License
|
|
220
226
|
|
|
221
227
|
MIT
|
package/dist/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../../src/platforms/slack/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,OAAO,EAAE,KAAK,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AAE5E,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,kBAAkB,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAI3F;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../../src/platforms/slack/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,OAAO,EAAE,KAAK,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AAE5E,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,kBAAkB,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAI3F;AAmND,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ1E;AAED,eAAO,MAAM,WAAW,SAsBrB,CAAA"}
|
|
@@ -3,7 +3,7 @@ import { handleError } from '../../../shared/utils/error-handler.js';
|
|
|
3
3
|
import { formatOutput } from '../../../shared/utils/output.js';
|
|
4
4
|
import { SlackClient, SlackError } from '../client.js';
|
|
5
5
|
import { CredentialManager } from '../credential-manager.js';
|
|
6
|
-
import { refreshCookie } from '../ensure-auth.js';
|
|
6
|
+
import { refreshCookie, tryWebTokenRefresh } from '../ensure-auth.js';
|
|
7
7
|
import { TokenExtractor } from '../token-extractor.js';
|
|
8
8
|
export function formatCredentialDebug(ws, showSecrets) {
|
|
9
9
|
const tokenDisplay = showSecrets ? ws.token : `${ws.token.substring(0, 20)}...`;
|
|
@@ -52,6 +52,7 @@ async function extractAction(options) {
|
|
|
52
52
|
}
|
|
53
53
|
const credManager = new CredentialManager();
|
|
54
54
|
const config = await credManager.load();
|
|
55
|
+
const workspaceDomains = extractor.getWorkspaceDomains();
|
|
55
56
|
const validWorkspaces = [];
|
|
56
57
|
const failureReasons = [];
|
|
57
58
|
for (const ws of workspaces) {
|
|
@@ -76,6 +77,23 @@ async function extractAction(options) {
|
|
|
76
77
|
if (options.debug) {
|
|
77
78
|
console.error(`[debug] β Invalid: ${error.message}`);
|
|
78
79
|
}
|
|
80
|
+
if (options.debug) {
|
|
81
|
+
const domain = workspaceDomains[ws.workspace_id];
|
|
82
|
+
console.error(`[debug] Attempting web token refresh for ${ws.workspace_id}${domain ? ` (${domain}.slack.com)` : ''}...`);
|
|
83
|
+
}
|
|
84
|
+
const refreshed = await tryWebTokenRefresh(ws, workspaceDomains);
|
|
85
|
+
if (refreshed) {
|
|
86
|
+
ws.token = refreshed.token;
|
|
87
|
+
ws.workspace_name = refreshed.workspace_name;
|
|
88
|
+
validWorkspaces.push(ws);
|
|
89
|
+
await credManager.setWorkspace(ws);
|
|
90
|
+
if (options.debug) {
|
|
91
|
+
console.error(`[debug] β Web refresh succeeded: ${refreshed.workspace_name}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (options.debug) {
|
|
95
|
+
console.error('[debug] β Web refresh failed');
|
|
96
|
+
}
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
if (validWorkspaces.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../../src/platforms/slack/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../../src/platforms/slack/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { CredentialManager } from './credential-manager.js';
|
|
2
|
+
import { type ExtractedWorkspace } from './token-extractor.js';
|
|
2
3
|
export declare function ensureSlackAuth(): Promise<void>;
|
|
4
|
+
export declare function tryWebTokenRefresh(ws: ExtractedWorkspace, workspaceDomains: Record<string, string>): Promise<{
|
|
5
|
+
token: string;
|
|
6
|
+
workspace_name: string;
|
|
7
|
+
} | null>;
|
|
8
|
+
export declare function refreshTokenFromWeb(domain: string, cookie: string): Promise<string | null>;
|
|
3
9
|
export declare function refreshCookie(token: string, credManager: CredentialManager): Promise<{
|
|
4
10
|
user_id: string;
|
|
5
11
|
team_id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensure-auth.d.ts","sourceRoot":"","sources":["../../../../src/platforms/slack/ensure-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"ensure-auth.d.ts","sourceRoot":"","sources":["../../../../src/platforms/slack/ensure-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,KAAK,kBAAkB,EAAkB,MAAM,mBAAmB,CAAA;AAE3E,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAiDrD;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAe3D;AAID,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAchG;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAiBpF"}
|
|
@@ -18,6 +18,7 @@ export async function ensureSlackAuth() {
|
|
|
18
18
|
try {
|
|
19
19
|
const extractor = new TokenExtractor();
|
|
20
20
|
const workspaces = await extractor.extract();
|
|
21
|
+
const workspaceDomains = extractor.getWorkspaceDomains();
|
|
21
22
|
const validWorkspaces = [];
|
|
22
23
|
for (const ws of workspaces) {
|
|
23
24
|
try {
|
|
@@ -27,7 +28,15 @@ export async function ensureSlackAuth() {
|
|
|
27
28
|
await credManager.setWorkspace(ws);
|
|
28
29
|
validWorkspaces.push(ws);
|
|
29
30
|
}
|
|
30
|
-
catch {
|
|
31
|
+
catch {
|
|
32
|
+
const refreshed = await tryWebTokenRefresh(ws, workspaceDomains);
|
|
33
|
+
if (refreshed) {
|
|
34
|
+
ws.token = refreshed.token;
|
|
35
|
+
ws.workspace_name = refreshed.workspace_name;
|
|
36
|
+
await credManager.setWorkspace(ws);
|
|
37
|
+
validWorkspaces.push(ws);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
const config = await credManager.load();
|
|
33
42
|
if (!config.current_workspace && validWorkspaces.length > 0) {
|
|
@@ -42,6 +51,41 @@ export async function ensureSlackAuth() {
|
|
|
42
51
|
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
54
|
+
export async function tryWebTokenRefresh(ws, workspaceDomains) {
|
|
55
|
+
if (!ws.cookie)
|
|
56
|
+
return null;
|
|
57
|
+
const domain = workspaceDomains[ws.workspace_id];
|
|
58
|
+
if (!domain)
|
|
59
|
+
return null;
|
|
60
|
+
try {
|
|
61
|
+
const freshToken = await refreshTokenFromWeb(domain, ws.cookie);
|
|
62
|
+
if (!freshToken)
|
|
63
|
+
return null;
|
|
64
|
+
const client = new SlackClient(freshToken, ws.cookie);
|
|
65
|
+
const authInfo = await client.testAuth();
|
|
66
|
+
return { token: freshToken, workspace_name: authInfo.team || ws.workspace_name };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const TOKEN_REGEX = /"api_token":"(xoxc-[a-zA-Z0-9-]+)"/;
|
|
73
|
+
export async function refreshTokenFromWeb(domain, cookie) {
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(`https://${domain}.slack.com/ssb/redirect`, {
|
|
76
|
+
headers: { Cookie: `d=${cookie}` },
|
|
77
|
+
redirect: 'follow',
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok)
|
|
80
|
+
return null;
|
|
81
|
+
const html = await response.text();
|
|
82
|
+
const match = html.match(TOKEN_REGEX);
|
|
83
|
+
return match?.[1] ?? null;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
45
89
|
export async function refreshCookie(token, credManager) {
|
|
46
90
|
try {
|
|
47
91
|
const extractor = new TokenExtractor();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensure-auth.js","sourceRoot":"","sources":["../../../../src/platforms/slack/ensure-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"ensure-auth.js","sourceRoot":"","sources":["../../../../src/platforms/slack/ensure-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAA2B,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAE3E,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAA;IAC3C,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,CAAA;IAElD,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;YACjE,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAA;YACvB,OAAM;QACR,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,MAAM,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC;gBAAE,OAAM;QAC/D,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,cAAc,EAAE,CAAA;QACtC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAA;QAC5C,MAAM,gBAAgB,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAA;QAExD,MAAM,eAAe,GAAG,EAAE,CAAA;QAC1B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;gBACnD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAA;gBACxC,EAAE,CAAC,cAAc,GAAG,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,cAAc,CAAA;gBACtD,MAAM,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;gBAClC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAA;gBAChE,IAAI,SAAS,EAAE,CAAC;oBACd,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAA;oBAC1B,EAAE,CAAC,cAAc,GAAG,SAAS,CAAC,cAAc,CAAA;oBAC5C,MAAM,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;oBAClC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;QACvC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,MAAM,WAAW,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;QACxE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAE,KAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;QAC5G,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtE,IAAI,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC/D,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAsB,EACtB,gBAAwC;IAExC,IAAI,CAAC,EAAE,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC3B,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,CAAC,YAAY,CAAC,CAAA;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;QAC/D,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAA;QAE5B,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;QACrD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAA;QACxC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,CAAA;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAG,oCAAoC,CAAA;AAExD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAc,EAAE,MAAc;IACtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,MAAM,yBAAyB,EAAE;YACvE,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,EAAE;YAClC,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QAE7B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACrC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,WAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,cAAc,EAAE,CAAA;QACtC,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,CAAA;QACnD,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QAE7B,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAA;QAExC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;QACvC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAClD,MAAM,WAAW,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
|
|
@@ -13,6 +13,7 @@ export declare class TokenExtractor {
|
|
|
13
13
|
constructor(platform?: NodeJS.Platform, slackDir?: string, keyCache?: DerivedKeyCache, debugLog?: (message: string) => void);
|
|
14
14
|
private debug;
|
|
15
15
|
getSlackDir(): string;
|
|
16
|
+
private findMsixSlackDir;
|
|
16
17
|
extractCookie(): Promise<string>;
|
|
17
18
|
extract(): Promise<ExtractedWorkspace[]>;
|
|
18
19
|
private extractTokensFromLevelDB;
|
|
@@ -22,6 +23,8 @@ export declare class TokenExtractor {
|
|
|
22
23
|
private extractFromLevelDB;
|
|
23
24
|
private extractViaClassicLevelCopy;
|
|
24
25
|
private extractViaClassicLevel;
|
|
26
|
+
private extractTokensFromBlobFiles;
|
|
27
|
+
private findFilesRecursive;
|
|
25
28
|
private extractTokensFromLDBFiles;
|
|
26
29
|
private extractTokenFromLogFile;
|
|
27
30
|
private extractTokenFromBuffer;
|
|
@@ -42,5 +45,6 @@ export declare class TokenExtractor {
|
|
|
42
45
|
private getDerivedKey;
|
|
43
46
|
private getDerivedKeyFromKeychain;
|
|
44
47
|
clearKeyCache(): Promise<void>;
|
|
48
|
+
getWorkspaceDomains(): Record<string, string>;
|
|
45
49
|
}
|
|
46
50
|
//# sourceMappingURL=token-extractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-extractor.d.ts","sourceRoot":"","sources":["../../../../src/platforms/slack/token-extractor.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AAIlE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;
|
|
1
|
+
{"version":3,"file":"token-extractor.d.ts","sourceRoot":"","sources":["../../../../src/platforms/slack/token-extractor.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AAIlE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAgCD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAoC;gBAGlD,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,EAC1B,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,eAAe,EAC1B,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAatC,OAAO,CAAC,KAAK;IAIb,WAAW,IAAI,MAAM;IAyCrB,OAAO,CAAC,gBAAgB;IAuClB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAoBhC,OAAO,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAqChC,wBAAwB;IAkCtC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,YAAY;YASN,kBAAkB;YAclB,0BAA0B;YA2B1B,sBAAsB;IAyBpC,OAAO,CAAC,0BAA0B;IAkClC,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,uBAAuB;IAmC/B,OAAO,CAAC,sBAAsB;IA8F9B,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,gBAAgB;YAqBV,uBAAuB;IAerC,OAAO,CAAC,gBAAgB;IAwExB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA6BlD,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,qBAAqB;IAiB7B,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BzD,mBAAmB,IAAI,MAAM,GAAG,IAAI;IA0BpC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAyB9C,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,aAAa,CAAQ;YAEf,kBAAkB;IA0BhC,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,yBAAyB;IAwB3B,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpC,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAyB9C"}
|
|
@@ -13,6 +13,7 @@ const SOURCE_PRIORITY = {
|
|
|
13
13
|
'json-single': 4,
|
|
14
14
|
'log-file': 3,
|
|
15
15
|
'classic-level': 2,
|
|
16
|
+
'blob-file': 1,
|
|
16
17
|
'ldb-file': 1,
|
|
17
18
|
};
|
|
18
19
|
const DIR_TIER_PRIORITY = {
|
|
@@ -55,12 +56,56 @@ export class TokenExtractor {
|
|
|
55
56
|
}
|
|
56
57
|
case 'linux':
|
|
57
58
|
return join(homedir(), '.config', 'Slack');
|
|
58
|
-
case 'win32':
|
|
59
|
+
case 'win32': {
|
|
60
|
+
// Check MSIX (Microsoft Store / GPO) package path first
|
|
61
|
+
const msixPath = this.findMsixSlackDir();
|
|
62
|
+
if (msixPath) {
|
|
63
|
+
return msixPath;
|
|
64
|
+
}
|
|
65
|
+
// Direct download version
|
|
59
66
|
return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Slack');
|
|
67
|
+
}
|
|
60
68
|
default:
|
|
61
69
|
throw new Error(`Unsupported platform: ${this.platform}`);
|
|
62
70
|
}
|
|
63
71
|
}
|
|
72
|
+
findMsixSlackDir() {
|
|
73
|
+
const packagesDir = join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Packages');
|
|
74
|
+
if (!existsSync(packagesDir)) {
|
|
75
|
+
this.debug('MSIX Packages directory not found');
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const entries = readdirSync(packagesDir, { withFileTypes: true });
|
|
80
|
+
let best = null;
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
if (!entry.isDirectory() || !entry.name.toLowerCase().includes('slack')) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const slackData = join(packagesDir, entry.name, 'LocalCache', 'Roaming', 'Slack');
|
|
86
|
+
this.debug(`Found MSIX candidate: ${entry.name}`);
|
|
87
|
+
if (!existsSync(join(slackData, 'storage')) && !existsSync(join(slackData, 'Local Storage'))) {
|
|
88
|
+
this.debug(` No Slack data at ${slackData}`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const mtime = statSync(slackData).mtimeMs;
|
|
92
|
+
this.debug(` Valid Slack data found (mtime: ${new Date(mtime).toISOString()})`);
|
|
93
|
+
if (!best || mtime > best.mtimeMs) {
|
|
94
|
+
best = { path: slackData, mtimeMs: mtime };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (best) {
|
|
98
|
+
this.debug(`Using MSIX Slack dir: ${best.path}`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.debug('No valid MSIX Slack data found, falling back to APPDATA');
|
|
102
|
+
}
|
|
103
|
+
return best?.path ?? null;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
64
109
|
async extractCookie() {
|
|
65
110
|
if (!existsSync(this.slackDir)) {
|
|
66
111
|
return '';
|
|
@@ -130,6 +175,9 @@ export class TokenExtractor {
|
|
|
130
175
|
}
|
|
131
176
|
catch { }
|
|
132
177
|
}
|
|
178
|
+
// Chromium offloads large IndexedDB values to external *.indexeddb.blob/ files
|
|
179
|
+
const blobTokens = this.extractTokensFromBlobFiles(baseDir, tier);
|
|
180
|
+
tokens.push(...blobTokens);
|
|
133
181
|
}
|
|
134
182
|
return this.deduplicateTokens(tokens);
|
|
135
183
|
}
|
|
@@ -246,6 +294,57 @@ export class TokenExtractor {
|
|
|
246
294
|
}
|
|
247
295
|
return tokens;
|
|
248
296
|
}
|
|
297
|
+
extractTokensFromBlobFiles(baseDir, dirTier) {
|
|
298
|
+
const tokens = [];
|
|
299
|
+
try {
|
|
300
|
+
const entries = readdirSync(baseDir, { withFileTypes: true });
|
|
301
|
+
for (const entry of entries) {
|
|
302
|
+
if (!entry.isDirectory() || !entry.name.endsWith('.indexeddb.blob'))
|
|
303
|
+
continue;
|
|
304
|
+
const blobDir = join(baseDir, entry.name);
|
|
305
|
+
this.debug(`Scanning blob directory: ${blobDir}`);
|
|
306
|
+
const files = this.findFilesRecursive(blobDir);
|
|
307
|
+
for (const filePath of files) {
|
|
308
|
+
try {
|
|
309
|
+
const stat = statSync(filePath);
|
|
310
|
+
if (stat.size > 10 * 1024 * 1024)
|
|
311
|
+
continue;
|
|
312
|
+
const content = readFileSync(filePath);
|
|
313
|
+
const xoxcMarker = Buffer.from('xoxc-');
|
|
314
|
+
let idx = content.indexOf(xoxcMarker, 0);
|
|
315
|
+
while (idx !== -1) {
|
|
316
|
+
const tokenData = this.extractTokenFromBuffer(content, idx);
|
|
317
|
+
if (tokenData) {
|
|
318
|
+
this.debug(`Found token in blob file: ${filePath}`);
|
|
319
|
+
tokens.push({ ...tokenData, source: 'blob-file', dirTier });
|
|
320
|
+
}
|
|
321
|
+
idx = content.indexOf(xoxcMarker, idx + 5);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch { }
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch { }
|
|
329
|
+
return tokens;
|
|
330
|
+
}
|
|
331
|
+
findFilesRecursive(dir) {
|
|
332
|
+
const files = [];
|
|
333
|
+
try {
|
|
334
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
335
|
+
for (const entry of entries) {
|
|
336
|
+
const fullPath = join(dir, entry.name);
|
|
337
|
+
if (entry.isDirectory()) {
|
|
338
|
+
files.push(...this.findFilesRecursive(fullPath));
|
|
339
|
+
}
|
|
340
|
+
else if (entry.isFile()) {
|
|
341
|
+
files.push(fullPath);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch { }
|
|
346
|
+
return files;
|
|
347
|
+
}
|
|
249
348
|
extractTokensFromLDBFiles(dbPath, dirTier) {
|
|
250
349
|
const tokens = [];
|
|
251
350
|
try {
|
|
@@ -697,5 +796,28 @@ export class TokenExtractor {
|
|
|
697
796
|
await this.keyCache.clear('slack');
|
|
698
797
|
this.cachedKey = null;
|
|
699
798
|
}
|
|
799
|
+
getWorkspaceDomains() {
|
|
800
|
+
const rootStatePath = join(this.slackDir, 'storage', 'root-state.json');
|
|
801
|
+
if (!existsSync(rootStatePath)) {
|
|
802
|
+
this.debug(`root-state.json not found at ${rootStatePath}`);
|
|
803
|
+
return {};
|
|
804
|
+
}
|
|
805
|
+
try {
|
|
806
|
+
const content = readFileSync(rootStatePath, 'utf8');
|
|
807
|
+
const data = JSON.parse(content);
|
|
808
|
+
const domains = {};
|
|
809
|
+
for (const [teamId, ws] of Object.entries(data.workspaces ?? {})) {
|
|
810
|
+
if (ws.domain) {
|
|
811
|
+
domains[teamId] = ws.domain;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
this.debug(`Found ${Object.keys(domains).length} workspace domain(s) in root-state.json`);
|
|
815
|
+
return domains;
|
|
816
|
+
}
|
|
817
|
+
catch {
|
|
818
|
+
this.debug('Failed to parse root-state.json');
|
|
819
|
+
return {};
|
|
820
|
+
}
|
|
821
|
+
}
|
|
700
822
|
}
|
|
701
823
|
//# sourceMappingURL=token-extractor.js.map
|