agent-messenger 1.0.0 → 1.1.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/.claude/commands/release.md +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/e2e.yml.disabled +69 -0
- package/README.md +16 -14
- package/biome.json +33 -1
- package/bun.lock +63 -0
- package/dist/package.json +8 -4
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +4 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/platforms/discord/cli.js +1 -1
- package/dist/src/platforms/discord/client.d.ts.map +1 -1
- package/dist/src/platforms/discord/client.js +3 -3
- package/dist/src/platforms/discord/client.js.map +1 -1
- package/dist/src/platforms/discord/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/user.js +10 -1
- package/dist/src/platforms/discord/commands/user.js.map +1 -1
- package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/discord/credential-manager.js +18 -12
- package/dist/src/platforms/discord/credential-manager.js.map +1 -1
- package/dist/src/platforms/slack/cli.js +1 -1
- package/dist/src/platforms/slack/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/slack/credential-manager.js +20 -6
- package/dist/src/platforms/slack/credential-manager.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +34 -9
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/dist/src/platforms/teams/cli.d.ts.map +1 -0
- package/dist/{cli.js → src/platforms/teams/cli.js} +11 -10
- package/dist/src/platforms/teams/cli.js.map +1 -0
- package/dist/src/platforms/teams/client.d.ts +32 -0
- package/dist/src/platforms/teams/client.d.ts.map +1 -0
- package/dist/src/platforms/teams/client.js +202 -0
- package/dist/src/platforms/teams/client.js.map +1 -0
- package/dist/src/platforms/teams/commands/auth.d.ts +14 -0
- package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/auth.js +176 -0
- package/dist/src/platforms/teams/commands/auth.js.map +1 -0
- package/dist/src/platforms/teams/commands/channel.d.ts +13 -0
- package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/channel.js +97 -0
- package/dist/src/platforms/teams/commands/channel.js.map +1 -0
- package/dist/src/platforms/teams/commands/file.d.ts +12 -0
- package/dist/src/platforms/teams/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/file.js +104 -0
- package/dist/src/platforms/teams/commands/file.js.map +1 -0
- package/dist/{commands → src/platforms/teams/commands}/index.d.ts +5 -2
- package/dist/src/platforms/teams/commands/index.d.ts.map +1 -0
- package/dist/{commands → src/platforms/teams/commands}/index.js +5 -2
- package/dist/src/platforms/teams/commands/index.js.map +1 -0
- package/dist/src/platforms/teams/commands/message.d.ts +17 -0
- package/dist/src/platforms/teams/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/message.js +133 -0
- package/dist/src/platforms/teams/commands/message.js.map +1 -0
- package/dist/src/platforms/teams/commands/reaction.d.ts +9 -0
- package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/reaction.js +68 -0
- package/dist/src/platforms/teams/commands/reaction.js.map +1 -0
- package/dist/src/platforms/teams/commands/snapshot.d.ts +10 -0
- package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/snapshot.js +85 -0
- package/dist/src/platforms/teams/commands/snapshot.js.map +1 -0
- package/dist/src/platforms/teams/commands/team.d.ts +18 -0
- package/dist/src/platforms/teams/commands/team.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/team.js +130 -0
- package/dist/src/platforms/teams/commands/team.js.map +1 -0
- package/dist/src/platforms/teams/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/teams/commands/user.js +88 -0
- package/dist/src/platforms/teams/commands/user.js.map +1 -0
- package/dist/src/platforms/teams/credential-manager.d.ts +18 -0
- package/dist/src/platforms/teams/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/teams/credential-manager.js +81 -0
- package/dist/src/platforms/teams/credential-manager.js.map +1 -0
- package/dist/src/platforms/teams/index.d.ts +4 -0
- package/dist/src/platforms/teams/index.d.ts.map +1 -0
- package/dist/src/platforms/teams/index.js +6 -0
- package/dist/src/platforms/teams/index.js.map +1 -0
- package/dist/src/platforms/teams/token-extractor.d.ts +36 -0
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -0
- package/dist/src/platforms/teams/token-extractor.js +335 -0
- package/dist/src/platforms/teams/token-extractor.js.map +1 -0
- package/dist/src/platforms/teams/types.d.ts +209 -0
- package/dist/src/platforms/teams/types.d.ts.map +1 -0
- package/dist/src/platforms/teams/types.js +65 -0
- package/dist/src/platforms/teams/types.js.map +1 -0
- package/docs/teams.md +321 -0
- package/e2e/README.md +256 -0
- package/e2e/config.ts +45 -0
- package/e2e/discord.e2e.test.ts +252 -0
- package/e2e/helpers.ts +107 -0
- package/e2e/slack.e2e.test.ts +309 -0
- package/package.json +8 -4
- package/scripts/postbuild.ts +15 -0
- package/skills/agent-teams/SKILL.md +292 -0
- package/skills/agent-teams/references/authentication.md +375 -0
- package/skills/agent-teams/references/common-patterns.md +596 -0
- package/skills/agent-teams/templates/monitor-channel.sh +239 -0
- package/skills/agent-teams/templates/post-message.sh +224 -0
- package/skills/agent-teams/templates/team-summary.sh +210 -0
- package/src/cli.ts +4 -0
- package/src/platforms/discord/client.ts +3 -3
- package/src/platforms/discord/commands/auth.test.ts +48 -32
- package/src/platforms/discord/commands/channel.test.ts +54 -42
- package/src/platforms/discord/commands/file.test.ts +40 -53
- package/src/platforms/discord/commands/guild.test.ts +47 -27
- package/src/platforms/discord/commands/message.test.ts +54 -51
- package/src/platforms/discord/commands/reaction.test.ts +54 -42
- package/src/platforms/discord/commands/user.ts +12 -1
- package/src/platforms/discord/credential-manager.test.ts +137 -136
- package/src/platforms/discord/credential-manager.ts +20 -13
- package/src/platforms/discord/token-extractor.test.ts +133 -383
- package/{tests → src/platforms/slack}/cli.test.ts +3 -3
- package/{tests/slack-client.test.ts → src/platforms/slack/client.test.ts} +1 -1
- package/{tests → src/platforms/slack}/commands/auth.test.ts +25 -13
- package/{tests → src/platforms/slack}/commands/channel.test.ts +2 -2
- package/{tests → src/platforms/slack}/commands/file.test.ts +2 -2
- package/{tests → src/platforms/slack}/commands/message.test.ts +2 -2
- package/{tests → src/platforms/slack}/commands/reaction.test.ts +1 -1
- package/{tests → src/platforms/slack}/commands/snapshot.test.ts +117 -105
- package/{tests → src/platforms/slack}/commands/user.test.ts +3 -3
- package/{tests → src/platforms/slack}/commands/workspace.test.ts +44 -95
- package/{tests → src/platforms/slack}/credential-manager.test.ts +2 -2
- package/src/platforms/slack/credential-manager.ts +22 -7
- package/src/platforms/slack/token-extractor-node-test.ts +40 -0
- package/src/platforms/slack/token-extractor-node.test.ts +10 -0
- package/src/platforms/slack/token-extractor.ts +36 -10
- package/{tests → src/platforms/slack}/types.test.ts +1 -1
- package/src/platforms/teams/cli.ts +36 -0
- package/src/platforms/teams/client.test.ts +500 -0
- package/src/platforms/teams/client.ts +365 -0
- package/src/platforms/teams/commands/auth.test.ts +99 -0
- package/src/platforms/teams/commands/auth.ts +232 -0
- package/src/platforms/teams/commands/channel.test.ts +147 -0
- package/src/platforms/teams/commands/channel.ts +129 -0
- package/src/platforms/teams/commands/file.test.ts +88 -0
- package/src/platforms/teams/commands/file.ts +144 -0
- package/src/platforms/teams/commands/index.ts +12 -0
- package/src/platforms/teams/commands/message.test.ts +110 -0
- package/src/platforms/teams/commands/message.ts +188 -0
- package/src/platforms/teams/commands/reaction.test.ts +87 -0
- package/src/platforms/teams/commands/reaction.ts +104 -0
- package/src/platforms/teams/commands/snapshot.test.ts +35 -0
- package/src/platforms/teams/commands/snapshot.ts +115 -0
- package/src/platforms/teams/commands/team.test.ts +157 -0
- package/src/platforms/teams/commands/team.ts +164 -0
- package/src/platforms/teams/commands/user.test.ts +83 -0
- package/src/platforms/teams/commands/user.ts +112 -0
- package/src/platforms/teams/credential-manager.test.ts +178 -0
- package/src/platforms/teams/credential-manager.ts +92 -0
- package/src/platforms/teams/index.ts +5 -0
- package/src/platforms/teams/token-extractor.test.ts +429 -0
- package/src/platforms/teams/token-extractor.ts +462 -0
- package/src/platforms/teams/types.test.ts +226 -0
- package/src/platforms/teams/types.ts +140 -0
- package/tsconfig.json +1 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -3
- package/dist/commands/auth.d.ts.map +0 -1
- package/dist/commands/auth.js +0 -140
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/channel.d.ts +0 -3
- package/dist/commands/channel.d.ts.map +0 -1
- package/dist/commands/channel.js +0 -118
- package/dist/commands/channel.js.map +0 -1
- package/dist/commands/file.d.ts +0 -3
- package/dist/commands/file.d.ts.map +0 -1
- package/dist/commands/file.js +0 -113
- package/dist/commands/file.js.map +0 -1
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/message.d.ts +0 -3
- package/dist/commands/message.d.ts.map +0 -1
- package/dist/commands/message.js +0 -214
- package/dist/commands/message.js.map +0 -1
- package/dist/commands/reaction.d.ts +0 -3
- package/dist/commands/reaction.d.ts.map +0 -1
- package/dist/commands/reaction.js +0 -100
- package/dist/commands/reaction.js.map +0 -1
- package/dist/commands/snapshot.d.ts +0 -3
- package/dist/commands/snapshot.d.ts.map +0 -1
- package/dist/commands/snapshot.js +0 -88
- package/dist/commands/snapshot.js.map +0 -1
- package/dist/commands/user.d.ts.map +0 -1
- package/dist/commands/user.js +0 -96
- package/dist/commands/user.js.map +0 -1
- package/dist/commands/workspace.d.ts +0 -3
- package/dist/commands/workspace.d.ts.map +0 -1
- package/dist/commands/workspace.js +0 -89
- package/dist/commands/workspace.js.map +0 -1
- package/dist/lib/credential-manager.d.ts +0 -13
- package/dist/lib/credential-manager.d.ts.map +0 -1
- package/dist/lib/credential-manager.js +0 -58
- package/dist/lib/credential-manager.js.map +0 -1
- package/dist/lib/index.d.ts +0 -3
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -3
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/ref-manager.d.ts +0 -26
- package/dist/lib/ref-manager.d.ts.map +0 -1
- package/dist/lib/ref-manager.js +0 -92
- package/dist/lib/ref-manager.js.map +0 -1
- package/dist/lib/slack-client.d.ts +0 -37
- package/dist/lib/slack-client.d.ts.map +0 -1
- package/dist/lib/slack-client.js +0 -379
- package/dist/lib/slack-client.js.map +0 -1
- package/dist/lib/token-extractor.d.ts +0 -28
- package/dist/lib/token-extractor.d.ts.map +0 -1
- package/dist/lib/token-extractor.js +0 -401
- package/dist/lib/token-extractor.js.map +0 -1
- package/dist/src/platforms/discord/client.test.d.ts +0 -2
- package/dist/src/platforms/discord/client.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/client.test.js +0 -367
- package/dist/src/platforms/discord/client.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/auth.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/auth.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/auth.test.js +0 -65
- package/dist/src/platforms/discord/commands/auth.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/channel.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/channel.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/channel.test.js +0 -136
- package/dist/src/platforms/discord/commands/channel.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/file.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/file.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/file.test.js +0 -83
- package/dist/src/platforms/discord/commands/file.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/guild.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/guild.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/guild.test.js +0 -100
- package/dist/src/platforms/discord/commands/guild.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/message.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/message.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/message.test.js +0 -91
- package/dist/src/platforms/discord/commands/message.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/reaction.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/reaction.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/reaction.test.js +0 -115
- package/dist/src/platforms/discord/commands/reaction.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/snapshot.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/snapshot.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/snapshot.test.js +0 -25
- package/dist/src/platforms/discord/commands/snapshot.test.js.map +0 -1
- package/dist/src/platforms/discord/commands/user.test.d.ts +0 -2
- package/dist/src/platforms/discord/commands/user.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/user.test.js +0 -103
- package/dist/src/platforms/discord/commands/user.test.js.map +0 -1
- package/dist/src/platforms/discord/credential-manager.test.d.ts +0 -2
- package/dist/src/platforms/discord/credential-manager.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/credential-manager.test.js +0 -136
- package/dist/src/platforms/discord/credential-manager.test.js.map +0 -1
- package/dist/src/platforms/discord/token-extractor.test.d.ts +0 -2
- package/dist/src/platforms/discord/token-extractor.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/token-extractor.test.js +0 -789
- package/dist/src/platforms/discord/token-extractor.test.js.map +0 -1
- package/dist/src/platforms/discord/types.test.d.ts +0 -2
- package/dist/src/platforms/discord/types.test.d.ts.map +0 -1
- package/dist/src/platforms/discord/types.test.js +0 -211
- package/dist/src/platforms/discord/types.test.js.map +0 -1
- package/dist/src/shared/utils/concurrency.test.d.ts +0 -2
- package/dist/src/shared/utils/concurrency.test.d.ts.map +0 -1
- package/dist/src/shared/utils/concurrency.test.js +0 -39
- package/dist/src/shared/utils/concurrency.test.js.map +0 -1
- package/dist/tests/cli.test.d.ts +0 -2
- package/dist/tests/cli.test.d.ts.map +0 -1
- package/dist/tests/cli.test.js +0 -83
- package/dist/tests/cli.test.js.map +0 -1
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/CURRENT +0 -1
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOCK +0 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG +0 -3
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG.old +0 -1
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/MANIFEST-000004 +0 -0
- package/dist/tests/commands/auth.test.d.ts +0 -2
- package/dist/tests/commands/auth.test.d.ts.map +0 -1
- package/dist/tests/commands/auth.test.js +0 -304
- package/dist/tests/commands/auth.test.js.map +0 -1
- package/dist/tests/commands/channel.test.d.ts +0 -2
- package/dist/tests/commands/channel.test.d.ts.map +0 -1
- package/dist/tests/commands/channel.test.js +0 -166
- package/dist/tests/commands/channel.test.js.map +0 -1
- package/dist/tests/commands/file.test.d.ts +0 -2
- package/dist/tests/commands/file.test.d.ts.map +0 -1
- package/dist/tests/commands/file.test.js +0 -175
- package/dist/tests/commands/file.test.js.map +0 -1
- package/dist/tests/commands/message.test.d.ts +0 -2
- package/dist/tests/commands/message.test.d.ts.map +0 -1
- package/dist/tests/commands/message.test.js +0 -293
- package/dist/tests/commands/message.test.js.map +0 -1
- package/dist/tests/commands/reaction.test.d.ts +0 -2
- package/dist/tests/commands/reaction.test.d.ts.map +0 -1
- package/dist/tests/commands/reaction.test.js +0 -84
- package/dist/tests/commands/reaction.test.js.map +0 -1
- package/dist/tests/commands/snapshot.test.d.ts +0 -2
- package/dist/tests/commands/snapshot.test.d.ts.map +0 -1
- package/dist/tests/commands/snapshot.test.js +0 -280
- package/dist/tests/commands/snapshot.test.js.map +0 -1
- package/dist/tests/commands/user.test.d.ts +0 -2
- package/dist/tests/commands/user.test.d.ts.map +0 -1
- package/dist/tests/commands/user.test.js +0 -117
- package/dist/tests/commands/user.test.js.map +0 -1
- package/dist/tests/commands/workspace.test.d.ts +0 -2
- package/dist/tests/commands/workspace.test.d.ts.map +0 -1
- package/dist/tests/commands/workspace.test.js +0 -453
- package/dist/tests/commands/workspace.test.js.map +0 -1
- package/dist/tests/credential-manager.test.d.ts +0 -2
- package/dist/tests/credential-manager.test.d.ts.map +0 -1
- package/dist/tests/credential-manager.test.js +0 -199
- package/dist/tests/credential-manager.test.js.map +0 -1
- package/dist/tests/slack-client.test.d.ts +0 -2
- package/dist/tests/slack-client.test.d.ts.map +0 -1
- package/dist/tests/slack-client.test.js +0 -741
- package/dist/tests/slack-client.test.js.map +0 -1
- package/dist/tests/types.test.d.ts +0 -2
- package/dist/tests/types.test.d.ts.map +0 -1
- package/dist/tests/types.test.js +0 -215
- package/dist/tests/types.test.js.map +0 -1
- package/dist/types/index.d.ts +0 -369
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -92
- package/dist/types/index.js.map +0 -1
- package/dist/utils/error-handler.d.ts +0 -2
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -5
- package/dist/utils/error-handler.js.map +0 -1
- package/dist/utils/output.d.ts +0 -2
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/output.js +0 -4
- package/dist/utils/output.js.map +0 -1
- /package/dist/{cli.d.ts → src/platforms/teams/cli.d.ts} +0 -0
- /package/dist/{commands → src/platforms/teams/commands}/user.d.ts +0 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, spyOn, test } from 'bun:test'
|
|
2
|
+
import { homedir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import { TeamsTokenExtractor } from './token-extractor'
|
|
6
|
+
|
|
7
|
+
describe('TeamsTokenExtractor', () => {
|
|
8
|
+
let extractor: TeamsTokenExtractor
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
extractor = new TeamsTokenExtractor()
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
describe('getTeamsCookiesPaths', () => {
|
|
15
|
+
test('returns darwin paths on macOS with New Teams first', () => {
|
|
16
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
17
|
+
const paths = darwinExtractor.getTeamsCookiesPaths()
|
|
18
|
+
|
|
19
|
+
expect(paths).toEqual([
|
|
20
|
+
join(
|
|
21
|
+
homedir(),
|
|
22
|
+
'Library',
|
|
23
|
+
'Containers',
|
|
24
|
+
'com.microsoft.teams2',
|
|
25
|
+
'Data',
|
|
26
|
+
'Library',
|
|
27
|
+
'Application Support',
|
|
28
|
+
'Microsoft',
|
|
29
|
+
'MSTeams',
|
|
30
|
+
'EBWebView',
|
|
31
|
+
'WV2Profile_tfw',
|
|
32
|
+
'Cookies'
|
|
33
|
+
),
|
|
34
|
+
join(
|
|
35
|
+
homedir(),
|
|
36
|
+
'Library',
|
|
37
|
+
'Containers',
|
|
38
|
+
'com.microsoft.teams2',
|
|
39
|
+
'Data',
|
|
40
|
+
'Library',
|
|
41
|
+
'Application Support',
|
|
42
|
+
'Microsoft',
|
|
43
|
+
'MSTeams',
|
|
44
|
+
'EBWebView',
|
|
45
|
+
'WV2Profile_tfl',
|
|
46
|
+
'Cookies'
|
|
47
|
+
),
|
|
48
|
+
join(
|
|
49
|
+
homedir(),
|
|
50
|
+
'Library',
|
|
51
|
+
'Containers',
|
|
52
|
+
'com.microsoft.teams2',
|
|
53
|
+
'Data',
|
|
54
|
+
'Library',
|
|
55
|
+
'Application Support',
|
|
56
|
+
'Microsoft',
|
|
57
|
+
'MSTeams',
|
|
58
|
+
'EBWebView',
|
|
59
|
+
'Default',
|
|
60
|
+
'Cookies'
|
|
61
|
+
),
|
|
62
|
+
join(homedir(), 'Library', 'Application Support', 'Microsoft', 'Teams', 'Cookies'),
|
|
63
|
+
])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('returns linux paths on Linux', () => {
|
|
67
|
+
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
68
|
+
const paths = linuxExtractor.getTeamsCookiesPaths()
|
|
69
|
+
|
|
70
|
+
expect(paths).toEqual([join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Cookies')])
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('returns win32 paths on Windows with New Teams first', () => {
|
|
74
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
75
|
+
const paths = winExtractor.getTeamsCookiesPaths()
|
|
76
|
+
|
|
77
|
+
const localAppData = process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local')
|
|
78
|
+
const appdata = process.env.APPDATA || join(homedir(), 'AppData', 'Roaming')
|
|
79
|
+
expect(paths).toEqual([
|
|
80
|
+
join(
|
|
81
|
+
localAppData,
|
|
82
|
+
'Packages',
|
|
83
|
+
'MSTeams_8wekyb3d8bbwe',
|
|
84
|
+
'LocalCache',
|
|
85
|
+
'Microsoft',
|
|
86
|
+
'MSTeams',
|
|
87
|
+
'EBWebView',
|
|
88
|
+
'WV2Profile_tfw',
|
|
89
|
+
'Cookies'
|
|
90
|
+
),
|
|
91
|
+
join(
|
|
92
|
+
localAppData,
|
|
93
|
+
'Packages',
|
|
94
|
+
'MSTeams_8wekyb3d8bbwe',
|
|
95
|
+
'LocalCache',
|
|
96
|
+
'Microsoft',
|
|
97
|
+
'MSTeams',
|
|
98
|
+
'EBWebView',
|
|
99
|
+
'WV2Profile_tfl',
|
|
100
|
+
'Cookies'
|
|
101
|
+
),
|
|
102
|
+
join(
|
|
103
|
+
localAppData,
|
|
104
|
+
'Packages',
|
|
105
|
+
'MSTeams_8wekyb3d8bbwe',
|
|
106
|
+
'LocalCache',
|
|
107
|
+
'Microsoft',
|
|
108
|
+
'MSTeams',
|
|
109
|
+
'EBWebView',
|
|
110
|
+
'Default',
|
|
111
|
+
'Cookies'
|
|
112
|
+
),
|
|
113
|
+
join(appdata, 'Microsoft', 'Teams', 'Cookies'),
|
|
114
|
+
])
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test('returns empty array for unsupported platform', () => {
|
|
118
|
+
const unsupportedExtractor = new TeamsTokenExtractor('freebsd' as NodeJS.Platform)
|
|
119
|
+
const paths = unsupportedExtractor.getTeamsCookiesPaths()
|
|
120
|
+
|
|
121
|
+
expect(paths).toEqual([])
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
describe('getLocalStatePath', () => {
|
|
126
|
+
test('returns darwin Local State path on macOS', () => {
|
|
127
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
128
|
+
const path = darwinExtractor.getLocalStatePath()
|
|
129
|
+
|
|
130
|
+
expect(path).toBe(
|
|
131
|
+
join(homedir(), 'Library', 'Application Support', 'Microsoft', 'Teams', 'Local State')
|
|
132
|
+
)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test('returns linux Local State path on Linux', () => {
|
|
136
|
+
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
137
|
+
const path = linuxExtractor.getLocalStatePath()
|
|
138
|
+
|
|
139
|
+
expect(path).toBe(join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Local State'))
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('returns win32 Local State path on Windows', () => {
|
|
143
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
144
|
+
const path = winExtractor.getLocalStatePath()
|
|
145
|
+
|
|
146
|
+
const appdata = process.env.APPDATA || join(homedir(), 'AppData', 'Roaming')
|
|
147
|
+
expect(path).toBe(join(appdata, 'Microsoft', 'Teams', 'Local State'))
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
describe('getKeychainVariants', () => {
|
|
152
|
+
test('returns keychain variants for macOS', () => {
|
|
153
|
+
const macExtractor = new TeamsTokenExtractor('darwin')
|
|
154
|
+
|
|
155
|
+
expect(macExtractor.getKeychainVariants()).toEqual([
|
|
156
|
+
{ service: 'Microsoft Teams Safe Storage', account: 'Microsoft Teams' },
|
|
157
|
+
{
|
|
158
|
+
service: 'Microsoft Teams (work or school) Safe Storage',
|
|
159
|
+
account: 'Microsoft Teams (work or school)',
|
|
160
|
+
},
|
|
161
|
+
{ service: 'Microsoft Edge Safe Storage', account: 'Microsoft Edge' },
|
|
162
|
+
{ service: 'Teams Safe Storage', account: 'Teams' },
|
|
163
|
+
])
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
describe('isValidSkypeToken', () => {
|
|
168
|
+
test('validates JWT-like skype token format', () => {
|
|
169
|
+
const validToken =
|
|
170
|
+
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature'
|
|
171
|
+
expect(extractor.isValidSkypeToken(validToken)).toBe(true)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test('validates long base64 token format', () => {
|
|
175
|
+
const validToken = 'a'.repeat(100)
|
|
176
|
+
expect(extractor.isValidSkypeToken(validToken)).toBe(true)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('rejects empty tokens', () => {
|
|
180
|
+
expect(extractor.isValidSkypeToken('')).toBe(false)
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
test('rejects short tokens', () => {
|
|
184
|
+
expect(extractor.isValidSkypeToken('short')).toBe(false)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
test('rejects null/undefined', () => {
|
|
188
|
+
expect(extractor.isValidSkypeToken(null as unknown as string)).toBe(false)
|
|
189
|
+
expect(extractor.isValidSkypeToken(undefined as unknown as string)).toBe(false)
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
describe('isEncryptedValue', () => {
|
|
194
|
+
test('detects v10 encrypted values', () => {
|
|
195
|
+
const encrypted = Buffer.from('v10encrypted_data')
|
|
196
|
+
expect(extractor.isEncryptedValue(encrypted)).toBe(true)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test('detects v11 encrypted values', () => {
|
|
200
|
+
const encrypted = Buffer.from('v11encrypted_data')
|
|
201
|
+
expect(extractor.isEncryptedValue(encrypted)).toBe(true)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
test('rejects non-encrypted values', () => {
|
|
205
|
+
const plain = Buffer.from('plain_text')
|
|
206
|
+
expect(extractor.isEncryptedValue(plain)).toBe(false)
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
test('rejects empty buffers', () => {
|
|
210
|
+
const empty = Buffer.alloc(0)
|
|
211
|
+
expect(extractor.isEncryptedValue(empty)).toBe(false)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('rejects short buffers', () => {
|
|
215
|
+
const short = Buffer.from('v1')
|
|
216
|
+
expect(extractor.isEncryptedValue(short)).toBe(false)
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
describe('extract', () => {
|
|
221
|
+
test('returns null when cookies path does not exist', async () => {
|
|
222
|
+
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
223
|
+
const extractFromCookiesDBSpy = spyOn(
|
|
224
|
+
linuxExtractor as any,
|
|
225
|
+
'extractFromCookiesDB'
|
|
226
|
+
).mockResolvedValue(null)
|
|
227
|
+
|
|
228
|
+
const result = await linuxExtractor.extract()
|
|
229
|
+
expect(result).toBeNull()
|
|
230
|
+
|
|
231
|
+
extractFromCookiesDBSpy.mockRestore()
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
test('extracts token from cookies database when available', async () => {
|
|
235
|
+
const mockToken =
|
|
236
|
+
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature_here'
|
|
237
|
+
|
|
238
|
+
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
239
|
+
const extractFromCookiesDBSpy = spyOn(
|
|
240
|
+
linuxExtractor as any,
|
|
241
|
+
'extractFromCookiesDB'
|
|
242
|
+
).mockResolvedValue(mockToken)
|
|
243
|
+
|
|
244
|
+
const result = await linuxExtractor.extract()
|
|
245
|
+
|
|
246
|
+
expect(result).not.toBeNull()
|
|
247
|
+
expect(result?.token).toBe(mockToken)
|
|
248
|
+
|
|
249
|
+
extractFromCookiesDBSpy.mockRestore()
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
test('returns null when extraction fails', async () => {
|
|
253
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
254
|
+
const extractFromCookiesDBSpy = spyOn(
|
|
255
|
+
darwinExtractor as any,
|
|
256
|
+
'extractFromCookiesDB'
|
|
257
|
+
).mockResolvedValue(null)
|
|
258
|
+
|
|
259
|
+
const result = await darwinExtractor.extract()
|
|
260
|
+
expect(result).toBeNull()
|
|
261
|
+
|
|
262
|
+
extractFromCookiesDBSpy.mockRestore()
|
|
263
|
+
})
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
describe('copyAndExtract', () => {
|
|
267
|
+
test('attempts to copy database to temp location', async () => {
|
|
268
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
269
|
+
|
|
270
|
+
const copyFileSpy = spyOn(darwinExtractor as any, 'copyDatabaseToTemp').mockReturnValue(
|
|
271
|
+
'/tmp/test-cookies'
|
|
272
|
+
)
|
|
273
|
+
const extractSpy = spyOn(darwinExtractor as any, 'extractFromSQLite').mockResolvedValue(
|
|
274
|
+
'test_token'
|
|
275
|
+
)
|
|
276
|
+
const cleanupSpy = spyOn(darwinExtractor as any, 'cleanupTempFile').mockImplementation(
|
|
277
|
+
() => {}
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
const result = await (darwinExtractor as any).copyAndExtract('/path/to/Cookies')
|
|
281
|
+
|
|
282
|
+
expect(copyFileSpy).toHaveBeenCalled()
|
|
283
|
+
expect(extractSpy).toHaveBeenCalled()
|
|
284
|
+
expect(cleanupSpy).toHaveBeenCalled()
|
|
285
|
+
expect(result).toBe('test_token')
|
|
286
|
+
|
|
287
|
+
copyFileSpy.mockRestore()
|
|
288
|
+
extractSpy.mockRestore()
|
|
289
|
+
cleanupSpy.mockRestore()
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
test('returns null when copy fails (file locked)', async () => {
|
|
293
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
294
|
+
|
|
295
|
+
const copyFileSpy = spyOn(darwinExtractor as any, 'copyDatabaseToTemp').mockImplementation(
|
|
296
|
+
() => {
|
|
297
|
+
throw new Error('EBUSY: resource busy or locked')
|
|
298
|
+
}
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
const result = await (darwinExtractor as any).copyAndExtract('/path/to/Cookies')
|
|
302
|
+
|
|
303
|
+
expect(result).toBeNull()
|
|
304
|
+
|
|
305
|
+
copyFileSpy.mockRestore()
|
|
306
|
+
})
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
describe('decryption', () => {
|
|
310
|
+
describe('decryptAESGCM', () => {
|
|
311
|
+
test('returns null for invalid encrypted data', () => {
|
|
312
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
313
|
+
const invalidData = Buffer.from('too_short')
|
|
314
|
+
const key = Buffer.alloc(32, 0)
|
|
315
|
+
|
|
316
|
+
const result = (darwinExtractor as any).decryptAESGCM(invalidData, key)
|
|
317
|
+
expect(result).toBeNull()
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('returns null when decryption fails', () => {
|
|
321
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
322
|
+
const fakeEncrypted = Buffer.concat([
|
|
323
|
+
Buffer.from('v10'),
|
|
324
|
+
Buffer.alloc(12, 1),
|
|
325
|
+
Buffer.alloc(20, 2),
|
|
326
|
+
Buffer.alloc(16, 3),
|
|
327
|
+
])
|
|
328
|
+
const key = Buffer.alloc(32, 0)
|
|
329
|
+
|
|
330
|
+
const result = (darwinExtractor as any).decryptAESGCM(fakeEncrypted, key)
|
|
331
|
+
expect(result).toBeNull()
|
|
332
|
+
})
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
describe('getKeychainPassword (macOS)', () => {
|
|
336
|
+
test('tries multiple keychain variants', async () => {
|
|
337
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
338
|
+
const execSyncSpy = spyOn(darwinExtractor as any, 'execSecurityCommand')
|
|
339
|
+
.mockReturnValueOnce(null)
|
|
340
|
+
.mockReturnValueOnce('test_password')
|
|
341
|
+
|
|
342
|
+
const result = (darwinExtractor as any).getKeychainPassword()
|
|
343
|
+
|
|
344
|
+
expect(execSyncSpy).toHaveBeenCalledTimes(2)
|
|
345
|
+
expect(result).toBe('test_password')
|
|
346
|
+
|
|
347
|
+
execSyncSpy.mockRestore()
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
test('returns null when all keychain variants fail', async () => {
|
|
351
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
352
|
+
const execSyncSpy = spyOn(darwinExtractor as any, 'execSecurityCommand').mockReturnValue(
|
|
353
|
+
null
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
const result = (darwinExtractor as any).getKeychainPassword()
|
|
357
|
+
|
|
358
|
+
expect(result).toBeNull()
|
|
359
|
+
|
|
360
|
+
execSyncSpy.mockRestore()
|
|
361
|
+
})
|
|
362
|
+
})
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
describe('process management', () => {
|
|
366
|
+
describe('isTeamsRunning', () => {
|
|
367
|
+
test('returns true when Teams process is found', async () => {
|
|
368
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
369
|
+
const checkProcessRunningSpy = spyOn(
|
|
370
|
+
darwinExtractor as any,
|
|
371
|
+
'checkProcessRunning'
|
|
372
|
+
).mockReturnValue(true)
|
|
373
|
+
|
|
374
|
+
const result = await darwinExtractor.isTeamsRunning()
|
|
375
|
+
expect(result).toBe(true)
|
|
376
|
+
|
|
377
|
+
checkProcessRunningSpy.mockRestore()
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
test('returns false when no Teams process is found', async () => {
|
|
381
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
382
|
+
const checkProcessRunningSpy = spyOn(
|
|
383
|
+
darwinExtractor as any,
|
|
384
|
+
'checkProcessRunning'
|
|
385
|
+
).mockReturnValue(false)
|
|
386
|
+
|
|
387
|
+
const result = await darwinExtractor.isTeamsRunning()
|
|
388
|
+
expect(result).toBe(false)
|
|
389
|
+
|
|
390
|
+
checkProcessRunningSpy.mockRestore()
|
|
391
|
+
})
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
describe('getProcessName', () => {
|
|
395
|
+
test('returns correct process name for macOS', () => {
|
|
396
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
397
|
+
expect((darwinExtractor as any).getProcessName()).toBe('Microsoft Teams')
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
test('returns correct process name for Windows', () => {
|
|
401
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
402
|
+
expect((winExtractor as any).getProcessName()).toBe('Teams.exe')
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
test('returns correct process name for Linux', () => {
|
|
406
|
+
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
407
|
+
expect((linuxExtractor as any).getProcessName()).toBe('teams')
|
|
408
|
+
})
|
|
409
|
+
})
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
describe('SQLite extraction', () => {
|
|
413
|
+
test('returns null when database path does not exist', async () => {
|
|
414
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
415
|
+
|
|
416
|
+
const result = await (darwinExtractor as any).extractFromSQLite('/nonexistent/path')
|
|
417
|
+
|
|
418
|
+
expect(result).toBeNull()
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
test('returns null when extraction throws', async () => {
|
|
422
|
+
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
423
|
+
|
|
424
|
+
const result = await (darwinExtractor as any).extractFromSQLite('/dev/null')
|
|
425
|
+
|
|
426
|
+
expect(result).toBeNull()
|
|
427
|
+
})
|
|
428
|
+
})
|
|
429
|
+
})
|