agent-messenger 2.10.1 → 2.11.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-plugin/plugin.json +1 -1
- package/.env.template +4 -1
- package/README.md +77 -27
- package/bun.lock +26 -0
- package/dist/package.json +14 -1
- package/dist/src/platforms/channeltalk/commands/auth.d.ts +2 -1
- package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/auth.js +5 -3
- package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.d.ts +2 -1
- package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.js +22 -6
- package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/cli.js +11 -1
- package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.js +1 -5
- package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/bot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/bot.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/bot.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/chat.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/chat.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/group.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/group.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/group.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/manager.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/manager.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/manager.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/message.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/message.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/whoami.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/credential-manager.d.ts +5 -0
- package/dist/src/platforms/channeltalkbot/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/credential-manager.js +34 -4
- package/dist/src/platforms/channeltalkbot/credential-manager.js.map +1 -1
- package/dist/src/platforms/discord/commands/auth.d.ts +1 -0
- package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/auth.js +3 -1
- package/dist/src/platforms/discord/commands/auth.js.map +1 -1
- package/dist/src/platforms/discord/listener.d.ts +2 -0
- package/dist/src/platforms/discord/listener.d.ts.map +1 -1
- package/dist/src/platforms/discord/listener.js +51 -21
- package/dist/src/platforms/discord/listener.js.map +1 -1
- package/dist/src/platforms/discord/token-extractor.d.ts +2 -1
- package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/discord/token-extractor.js +21 -6
- package/dist/src/platforms/discord/token-extractor.js.map +1 -1
- package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/cli.js +12 -1
- package/dist/src/platforms/discordbot/cli.js.map +1 -1
- package/dist/src/platforms/discordbot/client.d.ts +3 -0
- package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/client.js +3 -0
- package/dist/src/platforms/discordbot/client.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/auth.js +1 -5
- package/dist/src/platforms/discordbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.js +1 -6
- package/dist/src/platforms/discordbot/commands/message.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/server.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/server.js +1 -4
- package/dist/src/platforms/discordbot/commands/server.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/whoami.js +1 -6
- package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/discordbot/index.d.ts +3 -1
- package/dist/src/platforms/discordbot/index.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/index.js +2 -1
- package/dist/src/platforms/discordbot/index.js.map +1 -1
- package/dist/src/platforms/discordbot/listener.d.ts +43 -0
- package/dist/src/platforms/discordbot/listener.d.ts.map +1 -0
- package/dist/src/platforms/discordbot/listener.js +292 -0
- package/dist/src/platforms/discordbot/listener.js.map +1 -0
- package/dist/src/platforms/discordbot/types.d.ts +161 -0
- package/dist/src/platforms/discordbot/types.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/types.js +34 -0
- package/dist/src/platforms/discordbot/types.js.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.js +3 -1
- package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.d.ts +2 -1
- package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.js +11 -2
- package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/auth.js +4 -2
- package/dist/src/platforms/slack/commands/auth.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts +4 -1
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +64 -15
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/cli.js +15 -3
- package/dist/src/platforms/slackbot/cli.js.map +1 -1
- package/dist/src/platforms/slackbot/client.d.ts +22 -1
- package/dist/src/platforms/slackbot/client.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/client.js +104 -1
- package/dist/src/platforms/slackbot/client.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/auth.js +1 -5
- package/dist/src/platforms/slackbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/file.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/file.js +164 -0
- package/dist/src/platforms/slackbot/commands/file.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/index.js +1 -0
- package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/message.js +19 -0
- package/dist/src/platforms/slackbot/commands/message.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/whoami.js +1 -6
- package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/slackbot/credential-manager.d.ts +1 -0
- package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/credential-manager.js +30 -2
- package/dist/src/platforms/slackbot/credential-manager.js.map +1 -1
- package/dist/src/platforms/slackbot/index.d.ts +4 -1
- package/dist/src/platforms/slackbot/index.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/index.js +1 -0
- package/dist/src/platforms/slackbot/index.js.map +1 -1
- package/dist/src/platforms/slackbot/listener.d.ts +44 -0
- package/dist/src/platforms/slackbot/listener.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/listener.js +313 -0
- package/dist/src/platforms/slackbot/listener.js.map +1 -0
- package/dist/src/platforms/slackbot/types.d.ts +196 -1
- package/dist/src/platforms/slackbot/types.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/types.js +4 -1
- package/dist/src/platforms/slackbot/types.js.map +1 -1
- package/dist/src/platforms/teams/commands/auth.d.ts +1 -0
- package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/auth.js +37 -6
- package/dist/src/platforms/teams/commands/auth.js.map +1 -1
- package/dist/src/platforms/teams/ensure-auth.js +31 -9
- package/dist/src/platforms/teams/ensure-auth.js.map +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts +4 -1
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +80 -31
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts +1 -0
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +3 -1
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/token-extractor.d.ts +3 -1
- package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/webex/token-extractor.js +16 -2
- package/dist/src/platforms/webex/token-extractor.js.map +1 -1
- package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/cli.js +11 -1
- package/dist/src/platforms/wechatbot/cli.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/auth.js +1 -5
- package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.js +1 -6
- package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/template.js +1 -6
- package/dist/src/platforms/wechatbot/commands/template.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/user.js +1 -6
- package/dist/src/platforms/wechatbot/commands/user.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/whoami.js +1 -6
- package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/cli.js +11 -1
- package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.js +1 -5
- package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/template.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/template.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/template.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/whoami.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -1
- package/dist/src/shared/chromium/browsers.d.ts +8 -0
- package/dist/src/shared/chromium/browsers.d.ts.map +1 -1
- package/dist/src/shared/chromium/browsers.js +58 -3
- package/dist/src/shared/chromium/browsers.js.map +1 -1
- package/dist/src/shared/chromium/cli-options.d.ts +5 -0
- package/dist/src/shared/chromium/cli-options.d.ts.map +1 -0
- package/dist/src/shared/chromium/cli-options.js +8 -0
- package/dist/src/shared/chromium/cli-options.js.map +1 -0
- package/dist/src/shared/chromium/decryptor.d.ts +6 -0
- package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
- package/dist/src/shared/chromium/decryptor.js +26 -6
- package/dist/src/shared/chromium/decryptor.js.map +1 -1
- package/dist/src/shared/chromium/index.d.ts +3 -1
- package/dist/src/shared/chromium/index.d.ts.map +1 -1
- package/dist/src/shared/chromium/index.js +2 -1
- package/dist/src/shared/chromium/index.js.map +1 -1
- package/dist/src/shared/utils/cli-output.d.ts +7 -0
- package/dist/src/shared/utils/cli-output.d.ts.map +1 -0
- package/dist/src/shared/utils/cli-output.js +7 -0
- package/dist/src/shared/utils/cli-output.js.map +1 -0
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +73 -20
- package/dist/src/tui/app.js.map +1 -1
- package/docs/content/docs/cli/channeltalk.mdx +4 -0
- package/docs/content/docs/cli/discord.mdx +5 -0
- package/docs/content/docs/cli/instagram.mdx +3 -0
- package/docs/content/docs/cli/slack.mdx +5 -0
- package/docs/content/docs/cli/slackbot.mdx +60 -22
- package/docs/content/docs/cli/teams.mdx +5 -0
- package/docs/content/docs/cli/webex.mdx +3 -0
- package/docs/content/docs/sdk/channeltalkbot.mdx +38 -1
- package/docs/content/docs/sdk/discordbot.mdx +501 -0
- package/docs/content/docs/sdk/meta.json +2 -0
- package/docs/content/docs/sdk/slackbot.mdx +576 -0
- package/e2e/README.md +1 -1
- package/e2e/channeltalk.e2e.test.ts +13 -13
- package/e2e/channeltalkbot.e2e.test.ts +13 -13
- package/e2e/config.ts +9 -4
- package/e2e/discord.e2e.test.ts +24 -24
- package/e2e/discordbot.e2e.test.ts +16 -16
- package/e2e/instagram.e2e.test.ts +10 -10
- package/e2e/kakaotalk.e2e.test.ts +7 -7
- package/e2e/line.e2e.test.ts +8 -8
- package/e2e/slack.e2e.test.ts +34 -34
- package/e2e/slackbot.e2e.test.ts +14 -14
- package/e2e/teams.e2e.test.ts +23 -23
- package/e2e/telegram.e2e.test.ts +8 -8
- package/e2e/webex.e2e.test.ts +14 -14
- package/e2e/whatsapp.e2e.test.ts +8 -8
- package/e2e/whatsappbot.e2e.test.ts +6 -6
- package/examples/discordbot-listen.ts +65 -0
- package/examples/slackbot-listen.ts +65 -0
- package/package.json +14 -1
- package/skills/agent-channeltalk/SKILL.md +5 -1
- package/skills/agent-channeltalk/references/authentication.md +5 -1
- package/skills/agent-channeltalkbot/SKILL.md +17 -3
- package/skills/agent-channeltalkbot/references/authentication.md +7 -5
- package/skills/agent-discord/SKILL.md +5 -1
- package/skills/agent-discord/references/authentication.md +7 -1
- package/skills/agent-discordbot/SKILL.md +13 -2
- package/skills/agent-discordbot/references/common-patterns.md +1 -1
- package/skills/agent-instagram/SKILL.md +7 -1
- package/skills/agent-instagram/references/authentication.md +6 -0
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +5 -1
- package/skills/agent-slack/references/authentication.md +7 -1
- package/skills/agent-slackbot/SKILL.md +56 -4
- package/skills/agent-slackbot/references/authentication.md +4 -0
- package/skills/agent-teams/SKILL.md +5 -1
- package/skills/agent-teams/references/authentication.md +7 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +7 -1
- package/skills/agent-webex/references/authentication.md +6 -0
- package/skills/agent-wechatbot/SKILL.md +16 -1
- package/skills/agent-wechatbot/references/authentication.md +219 -0
- package/skills/agent-wechatbot/references/common-patterns.md +358 -0
- package/skills/agent-wechatbot/templates/account-summary.sh +122 -0
- package/skills/agent-wechatbot/templates/post-message.sh +122 -0
- package/skills/agent-wechatbot/templates/send-template.sh +152 -0
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +30 -1
- package/src/platforms/channeltalk/client.test.ts +26 -26
- package/src/platforms/channeltalk/commands/auth.test.ts +31 -19
- package/src/platforms/channeltalk/commands/auth.ts +15 -5
- package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
- package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
- package/src/platforms/channeltalk/commands/group.test.ts +4 -4
- package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
- package/src/platforms/channeltalk/commands/message.test.ts +17 -17
- package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
- package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
- package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
- package/src/platforms/channeltalk/index.test.ts +23 -23
- package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
- package/src/platforms/channeltalk/token-extractor.ts +24 -5
- package/src/platforms/channeltalk/types.test.ts +12 -12
- package/src/platforms/channeltalkbot/cli.ts +9 -0
- package/src/platforms/channeltalkbot/client.test.ts +14 -14
- package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalkbot/commands/auth.ts +1 -5
- package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/bot.ts +1 -6
- package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
- package/src/platforms/channeltalkbot/commands/chat.ts +1 -6
- package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/group.ts +1 -6
- package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
- package/src/platforms/channeltalkbot/commands/manager.ts +1 -6
- package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
- package/src/platforms/channeltalkbot/commands/message.ts +1 -6
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalkbot/commands/whoami.test.ts +6 -4
- package/src/platforms/channeltalkbot/commands/whoami.ts +1 -6
- package/src/platforms/channeltalkbot/credential-manager.test.ts +123 -29
- package/src/platforms/channeltalkbot/credential-manager.ts +37 -4
- package/src/platforms/channeltalkbot/index.test.ts +15 -15
- package/src/platforms/discord/client.test.ts +28 -28
- package/src/platforms/discord/commands/auth.test.ts +7 -7
- package/src/platforms/discord/commands/auth.ts +13 -2
- package/src/platforms/discord/commands/channel.test.ts +7 -7
- package/src/platforms/discord/commands/dm.test.ts +4 -4
- package/src/platforms/discord/commands/file.test.ts +4 -4
- package/src/platforms/discord/commands/friend.test.ts +6 -6
- package/src/platforms/discord/commands/member.test.ts +5 -5
- package/src/platforms/discord/commands/mention.test.ts +5 -5
- package/src/platforms/discord/commands/message.test.ts +9 -9
- package/src/platforms/discord/commands/note.test.ts +6 -6
- package/src/platforms/discord/commands/profile.test.ts +4 -4
- package/src/platforms/discord/commands/reaction.test.ts +5 -5
- package/src/platforms/discord/commands/server.test.ts +7 -7
- package/src/platforms/discord/commands/snapshot.test.ts +6 -6
- package/src/platforms/discord/commands/thread.test.ts +6 -6
- package/src/platforms/discord/commands/user.test.ts +5 -5
- package/src/platforms/discord/commands/whoami.test.ts +6 -6
- package/src/platforms/discord/credential-manager.test.ts +16 -16
- package/src/platforms/discord/ensure-auth.test.ts +8 -8
- package/src/platforms/discord/index.test.ts +17 -17
- package/src/platforms/discord/listener.test.ts +92 -34
- package/src/platforms/discord/listener.ts +43 -19
- package/src/platforms/discord/token-extractor.test.ts +53 -53
- package/src/platforms/discord/token-extractor.ts +30 -6
- package/src/platforms/discord/types.test.ts +26 -26
- package/src/platforms/discordbot/cli.ts +10 -0
- package/src/platforms/discordbot/client.test.ts +31 -31
- package/src/platforms/discordbot/client.ts +4 -0
- package/src/platforms/discordbot/commands/auth.test.ts +18 -18
- package/src/platforms/discordbot/commands/auth.ts +1 -5
- package/src/platforms/discordbot/commands/channel.test.ts +11 -11
- package/src/platforms/discordbot/commands/file.test.ts +7 -7
- package/src/platforms/discordbot/commands/message.test.ts +25 -25
- package/src/platforms/discordbot/commands/message.ts +1 -6
- package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
- package/src/platforms/discordbot/commands/server.test.ts +12 -12
- package/src/platforms/discordbot/commands/server.ts +1 -5
- package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
- package/src/platforms/discordbot/commands/thread.test.ts +10 -10
- package/src/platforms/discordbot/commands/user.test.ts +9 -9
- package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
- package/src/platforms/discordbot/commands/whoami.ts +1 -6
- package/src/platforms/discordbot/credential-manager.test.ts +28 -28
- package/src/platforms/discordbot/index.test.ts +82 -0
- package/src/platforms/discordbot/index.ts +27 -9
- package/src/platforms/discordbot/listener.test.ts +1002 -0
- package/src/platforms/discordbot/listener.ts +321 -0
- package/src/platforms/discordbot/types.ts +163 -0
- package/src/platforms/instagram/client.test.ts +18 -18
- package/src/platforms/instagram/commands/auth.test.ts +11 -11
- package/src/platforms/instagram/commands/auth.ts +9 -1
- package/src/platforms/instagram/commands/chat.test.ts +6 -6
- package/src/platforms/instagram/commands/message.test.ts +11 -11
- package/src/platforms/instagram/commands/shared.test.ts +12 -12
- package/src/platforms/instagram/commands/whoami.test.ts +3 -3
- package/src/platforms/instagram/credential-manager.test.ts +21 -21
- package/src/platforms/instagram/ensure-auth.test.ts +4 -4
- package/src/platforms/instagram/index.test.ts +9 -9
- package/src/platforms/instagram/listener.test.ts +8 -8
- package/src/platforms/instagram/token-extractor.test.ts +35 -35
- package/src/platforms/instagram/token-extractor.ts +13 -1
- package/src/platforms/kakaotalk/client.test.ts +33 -33
- package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
- package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
- package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
- package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
- package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
- package/src/platforms/kakaotalk/index.test.ts +15 -15
- package/src/platforms/kakaotalk/listener.test.ts +17 -17
- package/src/platforms/line/client.test.ts +17 -17
- package/src/platforms/line/commands/auth.test.ts +8 -8
- package/src/platforms/line/commands/chat.test.ts +7 -7
- package/src/platforms/line/commands/friend.test.ts +6 -6
- package/src/platforms/line/commands/message.test.ts +7 -7
- package/src/platforms/line/commands/whoami.test.ts +6 -6
- package/src/platforms/line/credential-manager.test.ts +17 -17
- package/src/platforms/line/index.test.ts +10 -10
- package/src/platforms/line/listener.test.ts +15 -15
- package/src/platforms/line/types.test.ts +14 -14
- package/src/platforms/slack/cli.test.ts +8 -8
- package/src/platforms/slack/client.test.ts +151 -151
- package/src/platforms/slack/commands/activity.test.ts +13 -13
- package/src/platforms/slack/commands/auth.test.ts +34 -34
- package/src/platforms/slack/commands/auth.ts +11 -2
- package/src/platforms/slack/commands/bookmark.test.ts +9 -9
- package/src/platforms/slack/commands/channel.test.ts +17 -17
- package/src/platforms/slack/commands/drafts.test.ts +7 -7
- package/src/platforms/slack/commands/emoji.test.ts +3 -3
- package/src/platforms/slack/commands/file.test.ts +12 -12
- package/src/platforms/slack/commands/message.test.ts +19 -19
- package/src/platforms/slack/commands/pin.test.ts +7 -7
- package/src/platforms/slack/commands/reaction.test.ts +10 -10
- package/src/platforms/slack/commands/reminder.test.ts +9 -9
- package/src/platforms/slack/commands/saved.test.ts +7 -7
- package/src/platforms/slack/commands/sections.test.ts +5 -5
- package/src/platforms/slack/commands/snapshot.test.ts +13 -13
- package/src/platforms/slack/commands/unread.test.ts +6 -6
- package/src/platforms/slack/commands/user.test.ts +10 -10
- package/src/platforms/slack/commands/usergroup.test.ts +15 -15
- package/src/platforms/slack/commands/whoami.test.ts +6 -6
- package/src/platforms/slack/commands/workspace.test.ts +26 -26
- package/src/platforms/slack/credential-manager.test.ts +14 -14
- package/src/platforms/slack/ensure-auth.test.ts +21 -21
- package/src/platforms/slack/index.test.ts +12 -12
- package/src/platforms/slack/listener.test.ts +17 -17
- package/src/platforms/slack/token-extractor-node.test.ts +2 -2
- package/src/platforms/slack/token-extractor.test.ts +133 -37
- package/src/platforms/slack/token-extractor.ts +76 -13
- package/src/platforms/slack/types.test.ts +21 -21
- package/src/platforms/slackbot/cli.ts +13 -1
- package/src/platforms/slackbot/client.test.ts +296 -22
- package/src/platforms/slackbot/client.ts +130 -2
- package/src/platforms/slackbot/commands/auth.test.ts +14 -14
- package/src/platforms/slackbot/commands/auth.ts +1 -5
- package/src/platforms/slackbot/commands/channel.test.ts +7 -7
- package/src/platforms/slackbot/commands/file.test.ts +201 -0
- package/src/platforms/slackbot/commands/file.ts +212 -0
- package/src/platforms/slackbot/commands/index.ts +1 -0
- package/src/platforms/slackbot/commands/message.test.ts +13 -13
- package/src/platforms/slackbot/commands/message.ts +22 -0
- package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
- package/src/platforms/slackbot/commands/user.test.ts +7 -7
- package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
- package/src/platforms/slackbot/commands/whoami.ts +1 -6
- package/src/platforms/slackbot/credential-manager.test.ts +83 -23
- package/src/platforms/slackbot/credential-manager.ts +32 -2
- package/src/platforms/slackbot/index.test.ts +59 -0
- package/src/platforms/slackbot/index.ts +31 -7
- package/src/platforms/slackbot/listener.test.ts +1012 -0
- package/src/platforms/slackbot/listener.ts +362 -0
- package/src/platforms/slackbot/types.test.ts +7 -7
- package/src/platforms/slackbot/types.ts +224 -1
- package/src/platforms/teams/client.test.ts +30 -30
- package/src/platforms/teams/commands/auth.test.ts +9 -9
- package/src/platforms/teams/commands/auth.ts +66 -7
- package/src/platforms/teams/commands/channel.test.ts +7 -7
- package/src/platforms/teams/commands/file.test.ts +4 -4
- package/src/platforms/teams/commands/message.test.ts +5 -5
- package/src/platforms/teams/commands/reaction.test.ts +4 -4
- package/src/platforms/teams/commands/snapshot.test.ts +7 -7
- package/src/platforms/teams/commands/team.test.ts +8 -8
- package/src/platforms/teams/commands/user.test.ts +4 -4
- package/src/platforms/teams/commands/whoami.test.ts +6 -6
- package/src/platforms/teams/credential-manager.test.ts +17 -17
- package/src/platforms/teams/ensure-auth.test.ts +69 -18
- package/src/platforms/teams/ensure-auth.ts +39 -11
- package/src/platforms/teams/index.test.ts +15 -15
- package/src/platforms/teams/token-extractor.test.ts +251 -69
- package/src/platforms/teams/token-extractor.ts +94 -31
- package/src/platforms/teams/types.test.ts +26 -26
- package/src/platforms/telegram/app-config.test.ts +4 -4
- package/src/platforms/telegram/chat-utils.test.ts +12 -12
- package/src/platforms/telegram/client.test.ts +4 -4
- package/src/platforms/telegram/commands/auth.test.ts +16 -16
- package/src/platforms/telegram/commands/chat.test.ts +9 -9
- package/src/platforms/telegram/commands/message.test.ts +6 -6
- package/src/platforms/telegram/commands/shared.test.ts +3 -3
- package/src/platforms/telegram/commands/whoami.test.ts +3 -3
- package/src/platforms/telegram/credential-manager.test.ts +10 -10
- package/src/platforms/telegram/types.test.ts +6 -6
- package/src/platforms/webex/app-config.test.ts +8 -8
- package/src/platforms/webex/cli.test.ts +5 -5
- package/src/platforms/webex/client.test.ts +65 -65
- package/src/platforms/webex/commands/auth.test.ts +18 -18
- package/src/platforms/webex/commands/auth.ts +13 -2
- package/src/platforms/webex/commands/member.test.ts +5 -5
- package/src/platforms/webex/commands/message.test.ts +12 -12
- package/src/platforms/webex/commands/snapshot.test.ts +5 -5
- package/src/platforms/webex/commands/space.test.ts +10 -10
- package/src/platforms/webex/commands/whoami.test.ts +6 -6
- package/src/platforms/webex/credential-manager.test.ts +22 -22
- package/src/platforms/webex/encryption.test.ts +4 -4
- package/src/platforms/webex/ensure-auth.test.ts +5 -5
- package/src/platforms/webex/index.test.ts +5 -5
- package/src/platforms/webex/markdown-to-html.test.ts +33 -33
- package/src/platforms/webex/token-extractor.test.ts +23 -23
- package/src/platforms/webex/token-extractor.ts +25 -3
- package/src/platforms/webex/types.test.ts +27 -27
- package/src/platforms/wechatbot/cli.ts +9 -0
- package/src/platforms/wechatbot/client.test.ts +27 -27
- package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
- package/src/platforms/wechatbot/commands/auth.ts +1 -5
- package/src/platforms/wechatbot/commands/message.test.ts +8 -8
- package/src/platforms/wechatbot/commands/message.ts +1 -6
- package/src/platforms/wechatbot/commands/template.test.ts +9 -9
- package/src/platforms/wechatbot/commands/template.ts +1 -6
- package/src/platforms/wechatbot/commands/user.test.ts +7 -7
- package/src/platforms/wechatbot/commands/user.ts +1 -6
- package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
- package/src/platforms/wechatbot/commands/whoami.ts +1 -6
- package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
- package/src/platforms/wechatbot/index.test.ts +10 -10
- package/src/platforms/wechatbot/types.test.ts +25 -25
- package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
- package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
- package/src/platforms/whatsapp/commands/message.test.ts +10 -10
- package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
- package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
- package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
- package/src/platforms/whatsapp/index.test.ts +8 -8
- package/src/platforms/whatsapp/types.test.ts +42 -42
- package/src/platforms/whatsappbot/cli.ts +9 -0
- package/src/platforms/whatsappbot/client.test.ts +27 -27
- package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
- package/src/platforms/whatsappbot/commands/auth.ts +1 -5
- package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
- package/src/platforms/whatsappbot/commands/message.ts +1 -6
- package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
- package/src/platforms/whatsappbot/commands/template.ts +1 -6
- package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
- package/src/platforms/whatsappbot/commands/whoami.ts +1 -6
- package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
- package/src/platforms/whatsappbot/index.test.ts +7 -7
- package/src/platforms/whatsappbot/types.test.ts +18 -18
- package/src/shared/chromium/browsers.test.ts +102 -22
- package/src/shared/chromium/browsers.ts +72 -3
- package/src/shared/chromium/cli-options.test.ts +22 -0
- package/src/shared/chromium/cli-options.ts +12 -0
- package/src/shared/chromium/cookie-reader.test.ts +13 -13
- package/src/shared/chromium/decryptor.test.ts +97 -32
- package/src/shared/chromium/decryptor.ts +27 -6
- package/src/shared/chromium/index.ts +3 -0
- package/src/shared/utils/cli-output.test.ts +57 -0
- package/src/shared/utils/cli-output.ts +8 -0
- package/src/shared/utils/concurrency.test.ts +6 -6
- package/src/shared/utils/derived-key-cache.test.ts +11 -11
- package/src/tui/app.ts +129 -20
- package/src/tui/utils.test.ts +31 -31
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, spyOn,
|
|
1
|
+
import { beforeEach, describe, expect, spyOn, it } from 'bun:test'
|
|
2
2
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
3
|
import { homedir, tmpdir } from 'node:os'
|
|
4
4
|
import { join } from 'node:path'
|
|
@@ -13,7 +13,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
13
13
|
})
|
|
14
14
|
|
|
15
15
|
describe('getDesktopCookiesPaths', () => {
|
|
16
|
-
|
|
16
|
+
it('returns darwin desktop paths on macOS', () => {
|
|
17
17
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
18
18
|
const paths = darwinExtractor.getDesktopCookiesPaths()
|
|
19
19
|
|
|
@@ -30,20 +30,33 @@ describe('TeamsTokenExtractor', () => {
|
|
|
30
30
|
'EBWebView',
|
|
31
31
|
)
|
|
32
32
|
expect(paths).toEqual([
|
|
33
|
-
{ path: join(darwinEbWebView, 'WV2Profile_tfw', 'Cookies'), accountType: 'work' },
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
{ path: join(darwinEbWebView, 'WV2Profile_tfw', 'Cookies'), accountType: 'work', accountTypeKnown: true },
|
|
34
|
+
{
|
|
35
|
+
path: join(darwinEbWebView, 'WV2Profile_tfw', 'Network', 'Cookies'),
|
|
36
|
+
accountType: 'work',
|
|
37
|
+
accountTypeKnown: true,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
path: join(darwinEbWebView, 'WV2Profile_tfl', 'Cookies'),
|
|
41
|
+
accountType: 'personal',
|
|
42
|
+
accountTypeKnown: true,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
path: join(darwinEbWebView, 'WV2Profile_tfl', 'Network', 'Cookies'),
|
|
46
|
+
accountType: 'personal',
|
|
47
|
+
accountTypeKnown: true,
|
|
48
|
+
},
|
|
49
|
+
{ path: join(darwinEbWebView, 'Default', 'Cookies'), accountType: 'work', accountTypeKnown: false },
|
|
50
|
+
{ path: join(darwinEbWebView, 'Default', 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false },
|
|
39
51
|
{
|
|
40
52
|
path: join(homedir(), 'Library', 'Application Support', 'Microsoft', 'Teams', 'Cookies'),
|
|
41
53
|
accountType: 'work',
|
|
54
|
+
accountTypeKnown: false,
|
|
42
55
|
},
|
|
43
56
|
])
|
|
44
57
|
})
|
|
45
58
|
|
|
46
|
-
|
|
59
|
+
it('returns linux desktop path on Linux', () => {
|
|
47
60
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
48
61
|
const paths = linuxExtractor.getDesktopCookiesPaths()
|
|
49
62
|
|
|
@@ -51,11 +64,12 @@ describe('TeamsTokenExtractor', () => {
|
|
|
51
64
|
{
|
|
52
65
|
path: join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Cookies'),
|
|
53
66
|
accountType: 'work',
|
|
67
|
+
accountTypeKnown: false,
|
|
54
68
|
},
|
|
55
69
|
])
|
|
56
70
|
})
|
|
57
71
|
|
|
58
|
-
|
|
72
|
+
it('returns win32 desktop paths on Windows', () => {
|
|
59
73
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
60
74
|
const paths = winExtractor.getDesktopCookiesPaths()
|
|
61
75
|
|
|
@@ -71,24 +85,32 @@ describe('TeamsTokenExtractor', () => {
|
|
|
71
85
|
'EBWebView',
|
|
72
86
|
)
|
|
73
87
|
expect(paths).toEqual([
|
|
74
|
-
{ path: join(winEbWebView, 'WV2Profile_tfw', 'Cookies'), accountType: 'work' },
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
{ path: join(
|
|
88
|
+
{ path: join(winEbWebView, 'WV2Profile_tfw', 'Cookies'), accountType: 'work', accountTypeKnown: true },
|
|
89
|
+
{
|
|
90
|
+
path: join(winEbWebView, 'WV2Profile_tfw', 'Network', 'Cookies'),
|
|
91
|
+
accountType: 'work',
|
|
92
|
+
accountTypeKnown: true,
|
|
93
|
+
},
|
|
94
|
+
{ path: join(winEbWebView, 'WV2Profile_tfl', 'Cookies'), accountType: 'personal', accountTypeKnown: true },
|
|
95
|
+
{
|
|
96
|
+
path: join(winEbWebView, 'WV2Profile_tfl', 'Network', 'Cookies'),
|
|
97
|
+
accountType: 'personal',
|
|
98
|
+
accountTypeKnown: true,
|
|
99
|
+
},
|
|
100
|
+
{ path: join(winEbWebView, 'Default', 'Cookies'), accountType: 'work', accountTypeKnown: false },
|
|
101
|
+
{ path: join(winEbWebView, 'Default', 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false },
|
|
102
|
+
{ path: join(appdata, 'Microsoft', 'Teams', 'Cookies'), accountType: 'work', accountTypeKnown: false },
|
|
81
103
|
])
|
|
82
104
|
})
|
|
83
105
|
|
|
84
|
-
|
|
106
|
+
it('returns empty array for unsupported platform', () => {
|
|
85
107
|
const unsupportedExtractor = new TeamsTokenExtractor('freebsd' as NodeJS.Platform)
|
|
86
108
|
expect(unsupportedExtractor.getDesktopCookiesPaths()).toEqual([])
|
|
87
109
|
})
|
|
88
110
|
})
|
|
89
111
|
|
|
90
112
|
describe('getBrowserCookiesPaths', () => {
|
|
91
|
-
|
|
113
|
+
it('returns browser cookie paths on macOS (at least Default profile per browser)', () => {
|
|
92
114
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
93
115
|
const paths = darwinExtractor.getBrowserCookiesPaths()
|
|
94
116
|
|
|
@@ -96,14 +118,16 @@ describe('TeamsTokenExtractor', () => {
|
|
|
96
118
|
expect(paths).toContainEqual({
|
|
97
119
|
path: join(chromeBase, 'Default', 'Cookies'),
|
|
98
120
|
accountType: 'work',
|
|
121
|
+
accountTypeKnown: false,
|
|
99
122
|
})
|
|
100
123
|
expect(paths).toContainEqual({
|
|
101
124
|
path: join(chromeBase, 'Default', 'Network', 'Cookies'),
|
|
102
125
|
accountType: 'work',
|
|
126
|
+
accountTypeKnown: false,
|
|
103
127
|
})
|
|
104
128
|
})
|
|
105
129
|
|
|
106
|
-
|
|
130
|
+
it('returns browser cookie paths on Linux', () => {
|
|
107
131
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
108
132
|
const paths = linuxExtractor.getBrowserCookiesPaths()
|
|
109
133
|
|
|
@@ -111,10 +135,11 @@ describe('TeamsTokenExtractor', () => {
|
|
|
111
135
|
expect(paths).toContainEqual({
|
|
112
136
|
path: join(chromeBase, 'Default', 'Cookies'),
|
|
113
137
|
accountType: 'work',
|
|
138
|
+
accountTypeKnown: false,
|
|
114
139
|
})
|
|
115
140
|
})
|
|
116
141
|
|
|
117
|
-
|
|
142
|
+
it('returns browser cookie paths on Windows', () => {
|
|
118
143
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
119
144
|
const paths = winExtractor.getBrowserCookiesPaths()
|
|
120
145
|
|
|
@@ -123,23 +148,28 @@ describe('TeamsTokenExtractor', () => {
|
|
|
123
148
|
expect(paths).toContainEqual({
|
|
124
149
|
path: join(chromeBase, 'Default', 'Cookies'),
|
|
125
150
|
accountType: 'work',
|
|
151
|
+
accountTypeKnown: false,
|
|
126
152
|
})
|
|
127
153
|
})
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
it('returns empty array for unsupported platform', () => {
|
|
130
156
|
const unsupportedExtractor = new TeamsTokenExtractor('freebsd' as NodeJS.Platform)
|
|
131
157
|
expect(unsupportedExtractor.getBrowserCookiesPaths()).toEqual([])
|
|
132
158
|
})
|
|
133
159
|
|
|
134
|
-
|
|
160
|
+
// Regression for #163: browser paths must not assert accountType confidently because
|
|
161
|
+
// Chromium profile paths don't encode work vs personal. Desktop WV2Profile_tfw/_tfl
|
|
162
|
+
// paths are authoritative; browsers must be probed at validation time.
|
|
163
|
+
it('browser paths have accountTypeKnown=false so they get probed at validation', () => {
|
|
135
164
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
136
165
|
const paths = darwinExtractor.getBrowserCookiesPaths()
|
|
137
|
-
expect(paths.
|
|
166
|
+
expect(paths.length).toBeGreaterThan(0)
|
|
167
|
+
expect(paths.every((p) => p.accountTypeKnown === false)).toBe(true)
|
|
138
168
|
})
|
|
139
169
|
})
|
|
140
170
|
|
|
141
171
|
describe('getTeamsCookiesPaths', () => {
|
|
142
|
-
|
|
172
|
+
it('returns darwin paths on macOS with desktop paths first', () => {
|
|
143
173
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
144
174
|
const paths = darwinExtractor.getTeamsCookiesPaths()
|
|
145
175
|
const desktopPaths = darwinExtractor.getDesktopCookiesPaths()
|
|
@@ -147,7 +177,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
147
177
|
expect(paths.slice(0, desktopPaths.length)).toEqual(desktopPaths)
|
|
148
178
|
})
|
|
149
179
|
|
|
150
|
-
|
|
180
|
+
it('browser paths come after desktop paths on macOS', () => {
|
|
151
181
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
152
182
|
const paths = darwinExtractor.getTeamsCookiesPaths()
|
|
153
183
|
const desktopPaths = darwinExtractor.getDesktopCookiesPaths()
|
|
@@ -157,7 +187,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
157
187
|
expect(paths.slice(desktopPaths.length)).toEqual(browserPaths)
|
|
158
188
|
})
|
|
159
189
|
|
|
160
|
-
|
|
190
|
+
it('returns linux paths with desktop first then browser paths', () => {
|
|
161
191
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
162
192
|
const paths = linuxExtractor.getTeamsCookiesPaths()
|
|
163
193
|
const desktopPaths = linuxExtractor.getDesktopCookiesPaths()
|
|
@@ -166,12 +196,13 @@ describe('TeamsTokenExtractor', () => {
|
|
|
166
196
|
{
|
|
167
197
|
path: join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Cookies'),
|
|
168
198
|
accountType: 'work',
|
|
199
|
+
accountTypeKnown: false,
|
|
169
200
|
},
|
|
170
201
|
])
|
|
171
202
|
expect(paths.length).toBeGreaterThan(desktopPaths.length)
|
|
172
203
|
})
|
|
173
204
|
|
|
174
|
-
|
|
205
|
+
it('returns win32 paths with desktop first then browser paths', () => {
|
|
175
206
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
176
207
|
const paths = winExtractor.getTeamsCookiesPaths()
|
|
177
208
|
const desktopPaths = winExtractor.getDesktopCookiesPaths()
|
|
@@ -180,7 +211,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
180
211
|
expect(paths.length).toBeGreaterThan(desktopPaths.length)
|
|
181
212
|
})
|
|
182
213
|
|
|
183
|
-
|
|
214
|
+
it('returns empty array for unsupported platform', () => {
|
|
184
215
|
const unsupportedExtractor = new TeamsTokenExtractor('freebsd' as NodeJS.Platform)
|
|
185
216
|
const paths = unsupportedExtractor.getTeamsCookiesPaths()
|
|
186
217
|
|
|
@@ -189,21 +220,21 @@ describe('TeamsTokenExtractor', () => {
|
|
|
189
220
|
})
|
|
190
221
|
|
|
191
222
|
describe('getLocalStatePath', () => {
|
|
192
|
-
|
|
223
|
+
it('returns darwin Local State path on macOS', () => {
|
|
193
224
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
194
225
|
const path = darwinExtractor.getLocalStatePath()
|
|
195
226
|
|
|
196
227
|
expect(path).toBe(join(homedir(), 'Library', 'Application Support', 'Microsoft', 'Teams', 'Local State'))
|
|
197
228
|
})
|
|
198
229
|
|
|
199
|
-
|
|
230
|
+
it('returns linux Local State path on Linux', () => {
|
|
200
231
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
201
232
|
const path = linuxExtractor.getLocalStatePath()
|
|
202
233
|
|
|
203
234
|
expect(path).toBe(join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Local State'))
|
|
204
235
|
})
|
|
205
236
|
|
|
206
|
-
|
|
237
|
+
it('returns win32 Local State path on Windows', () => {
|
|
207
238
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
208
239
|
const path = winExtractor.getLocalStatePath()
|
|
209
240
|
|
|
@@ -213,7 +244,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
213
244
|
})
|
|
214
245
|
|
|
215
246
|
describe('getKeychainVariants', () => {
|
|
216
|
-
|
|
247
|
+
it('includes Teams-specific keychain entries', () => {
|
|
217
248
|
const macExtractor = new TeamsTokenExtractor('darwin')
|
|
218
249
|
const variants = macExtractor.getKeychainVariants()
|
|
219
250
|
|
|
@@ -226,7 +257,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
226
257
|
expect(variants).toContainEqual({ service: 'Teams Safe Storage', account: 'Teams' })
|
|
227
258
|
})
|
|
228
259
|
|
|
229
|
-
|
|
260
|
+
it('includes browser keychain entries appended after Teams entries', () => {
|
|
230
261
|
const macExtractor = new TeamsTokenExtractor('darwin')
|
|
231
262
|
const variants = macExtractor.getKeychainVariants()
|
|
232
263
|
|
|
@@ -238,7 +269,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
238
269
|
expect(variants).toContainEqual({ service: 'Chromium Safe Storage', account: 'Chromium' })
|
|
239
270
|
})
|
|
240
271
|
|
|
241
|
-
|
|
272
|
+
it('Teams entries come before browser entries', () => {
|
|
242
273
|
const macExtractor = new TeamsTokenExtractor('darwin')
|
|
243
274
|
const variants = macExtractor.getKeychainVariants()
|
|
244
275
|
|
|
@@ -249,59 +280,81 @@ describe('TeamsTokenExtractor', () => {
|
|
|
249
280
|
})
|
|
250
281
|
|
|
251
282
|
describe('isValidSkypeToken', () => {
|
|
252
|
-
|
|
283
|
+
it('validates JWT-like skype token format', () => {
|
|
253
284
|
const validToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature'
|
|
254
285
|
expect(extractor.isValidSkypeToken(validToken)).toBe(true)
|
|
255
286
|
})
|
|
256
287
|
|
|
257
|
-
|
|
288
|
+
it('validates long base64 token format', () => {
|
|
258
289
|
const validToken = 'a'.repeat(100)
|
|
259
290
|
expect(extractor.isValidSkypeToken(validToken)).toBe(true)
|
|
260
291
|
})
|
|
261
292
|
|
|
262
|
-
|
|
293
|
+
it('rejects empty tokens', () => {
|
|
263
294
|
expect(extractor.isValidSkypeToken('')).toBe(false)
|
|
264
295
|
})
|
|
265
296
|
|
|
266
|
-
|
|
297
|
+
it('rejects short tokens', () => {
|
|
267
298
|
expect(extractor.isValidSkypeToken('short')).toBe(false)
|
|
268
299
|
})
|
|
269
300
|
|
|
270
|
-
|
|
301
|
+
it('rejects null/undefined', () => {
|
|
271
302
|
expect(extractor.isValidSkypeToken(null as unknown as string)).toBe(false)
|
|
272
303
|
expect(extractor.isValidSkypeToken(undefined as unknown as string)).toBe(false)
|
|
273
304
|
})
|
|
305
|
+
|
|
306
|
+
// Regression for #156: PowerShell CLIXML leaks into DPAPI output on Windows.
|
|
307
|
+
it('rejects CLIXML progress-stream contamination', () => {
|
|
308
|
+
// given: the exact shape of the leak reported in #156
|
|
309
|
+
const clixml =
|
|
310
|
+
'#< CLIXML\r\n<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">' +
|
|
311
|
+
'<Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.Automation.PSCustomObject</T>' +
|
|
312
|
+
'<T>System.Object</T></TN><MS><I64 N="SourceId">1</I64></MS></Obj></Objs>'
|
|
313
|
+
|
|
314
|
+
// then
|
|
315
|
+
expect(extractor.isValidSkypeToken(clixml)).toBe(false)
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
it('rejects anything containing angle brackets or whitespace', () => {
|
|
319
|
+
expect(extractor.isValidSkypeToken('a'.repeat(60) + '<div>')).toBe(false)
|
|
320
|
+
expect(extractor.isValidSkypeToken('a'.repeat(40) + ' ' + 'b'.repeat(40))).toBe(false)
|
|
321
|
+
expect(extractor.isValidSkypeToken('a'.repeat(40) + '\n' + 'b'.repeat(40))).toBe(false)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('rejects a bare 36-char UUID', () => {
|
|
325
|
+
expect(extractor.isValidSkypeToken('12345678-1234-1234-1234-123456789012')).toBe(false)
|
|
326
|
+
})
|
|
274
327
|
})
|
|
275
328
|
|
|
276
329
|
describe('isEncryptedValue', () => {
|
|
277
|
-
|
|
330
|
+
it('detects v10 encrypted values', () => {
|
|
278
331
|
const encrypted = Buffer.from('v10encrypted_data')
|
|
279
332
|
expect(extractor.isEncryptedValue(encrypted)).toBe(true)
|
|
280
333
|
})
|
|
281
334
|
|
|
282
|
-
|
|
335
|
+
it('detects v11 encrypted values', () => {
|
|
283
336
|
const encrypted = Buffer.from('v11encrypted_data')
|
|
284
337
|
expect(extractor.isEncryptedValue(encrypted)).toBe(true)
|
|
285
338
|
})
|
|
286
339
|
|
|
287
|
-
|
|
340
|
+
it('rejects non-encrypted values', () => {
|
|
288
341
|
const plain = Buffer.from('plain_text')
|
|
289
342
|
expect(extractor.isEncryptedValue(plain)).toBe(false)
|
|
290
343
|
})
|
|
291
344
|
|
|
292
|
-
|
|
345
|
+
it('rejects empty buffers', () => {
|
|
293
346
|
const empty = Buffer.alloc(0)
|
|
294
347
|
expect(extractor.isEncryptedValue(empty)).toBe(false)
|
|
295
348
|
})
|
|
296
349
|
|
|
297
|
-
|
|
350
|
+
it('rejects short buffers', () => {
|
|
298
351
|
const short = Buffer.from('v1')
|
|
299
352
|
expect(extractor.isEncryptedValue(short)).toBe(false)
|
|
300
353
|
})
|
|
301
354
|
})
|
|
302
355
|
|
|
303
356
|
describe('extract', () => {
|
|
304
|
-
|
|
357
|
+
it('returns null when cookies path does not exist', async () => {
|
|
305
358
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
306
359
|
const extractFromCookiesDBSpy = spyOn(linuxExtractor as any, 'extractFromCookiesDB').mockResolvedValue([])
|
|
307
360
|
|
|
@@ -311,12 +364,12 @@ describe('TeamsTokenExtractor', () => {
|
|
|
311
364
|
extractFromCookiesDBSpy.mockRestore()
|
|
312
365
|
})
|
|
313
366
|
|
|
314
|
-
|
|
367
|
+
it('extracts token from cookies database when available', async () => {
|
|
315
368
|
const mockToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature_here'
|
|
316
369
|
|
|
317
370
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
318
371
|
const extractFromCookiesDBSpy = spyOn(linuxExtractor as any, 'extractFromCookiesDB').mockResolvedValue([
|
|
319
|
-
{ token: mockToken, accountType: 'work' },
|
|
372
|
+
{ token: mockToken, accountType: 'work', accountTypeKnown: true },
|
|
320
373
|
])
|
|
321
374
|
|
|
322
375
|
const result = await linuxExtractor.extract()
|
|
@@ -327,7 +380,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
327
380
|
extractFromCookiesDBSpy.mockRestore()
|
|
328
381
|
})
|
|
329
382
|
|
|
330
|
-
|
|
383
|
+
it('returns null when extraction fails', async () => {
|
|
331
384
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
332
385
|
const extractFromCookiesDBSpy = spyOn(darwinExtractor as any, 'extractFromCookiesDB').mockResolvedValue([])
|
|
333
386
|
|
|
@@ -349,7 +402,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
349
402
|
const cleanup = () => rmSync(workDir, { recursive: true, force: true })
|
|
350
403
|
|
|
351
404
|
// Regression for #156: if only Network/Cookies exists, missing sibling must not poison accountType.
|
|
352
|
-
|
|
405
|
+
it('falls through to Network/Cookies when Cookies is missing', async () => {
|
|
353
406
|
// given: only Network/Cookies exists on disk for WV2Profile_tfl
|
|
354
407
|
const profileDir = join(workDir, 'WV2Profile_tfl')
|
|
355
408
|
const networkDir = join(profileDir, 'Network')
|
|
@@ -360,8 +413,8 @@ describe('TeamsTokenExtractor', () => {
|
|
|
360
413
|
|
|
361
414
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
362
415
|
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
363
|
-
{ path: cookiesPath, accountType: 'personal' },
|
|
364
|
-
{ path: networkCookiesPath, accountType: 'personal' },
|
|
416
|
+
{ path: cookiesPath, accountType: 'personal', accountTypeKnown: true },
|
|
417
|
+
{ path: networkCookiesPath, accountType: 'personal', accountTypeKnown: true },
|
|
365
418
|
])
|
|
366
419
|
const tried: string[] = []
|
|
367
420
|
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract').mockImplementation(async (...args) => {
|
|
@@ -376,14 +429,143 @@ describe('TeamsTokenExtractor', () => {
|
|
|
376
429
|
// then: the Cookies path was skipped (never passed to copyAndExtract),
|
|
377
430
|
// the Network/Cookies sibling was tried, and the token was returned.
|
|
378
431
|
expect(tried).toEqual([networkCookiesPath])
|
|
379
|
-
expect(results).toEqual([{ token: mockToken, accountType: 'personal' }])
|
|
432
|
+
expect(results).toEqual([{ token: mockToken, accountType: 'personal', accountTypeKnown: true }])
|
|
433
|
+
|
|
434
|
+
getPathsSpy.mockRestore()
|
|
435
|
+
copyAndExtractSpy.mockRestore()
|
|
436
|
+
cleanup()
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
// Regression for #156: CLIXML-contaminated decrypt output must not short-circuit
|
|
440
|
+
// the work account, leaving other valid paths unvisited.
|
|
441
|
+
it('does not mark accountType seen when the first path yields CLIXML garbage', async () => {
|
|
442
|
+
// given: first work path returns CLIXML garbage, second work path returns a real token
|
|
443
|
+
const clixmlGarbage =
|
|
444
|
+
'#< CLIXML\r\n<Objs xmlns="http://schemas.microsoft.com/powershell/2004/04">' +
|
|
445
|
+
'<Obj S="progress"><TN><T>Progress</T></TN></Obj></Objs>\r\n' +
|
|
446
|
+
'a'.repeat(80)
|
|
447
|
+
const realToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature_here'
|
|
448
|
+
|
|
449
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
450
|
+
const firstPath = join(workDir, 'WV2Profile_tfw', 'Cookies')
|
|
451
|
+
const secondPath = join(workDir, 'Default', 'Network', 'Cookies')
|
|
452
|
+
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
453
|
+
{ path: firstPath, accountType: 'work', accountTypeKnown: true },
|
|
454
|
+
{ path: secondPath, accountType: 'work', accountTypeKnown: true },
|
|
455
|
+
])
|
|
456
|
+
mkdirSync(join(workDir, 'WV2Profile_tfw'), { recursive: true })
|
|
457
|
+
mkdirSync(join(workDir, 'Default', 'Network'), { recursive: true })
|
|
458
|
+
writeFileSync(firstPath, '')
|
|
459
|
+
writeFileSync(secondPath, '')
|
|
460
|
+
|
|
461
|
+
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract')
|
|
462
|
+
.mockResolvedValueOnce(clixmlGarbage)
|
|
463
|
+
.mockResolvedValueOnce(realToken)
|
|
464
|
+
|
|
465
|
+
// when
|
|
466
|
+
const results = await (winExtractor as any).extractFromCookiesDB()
|
|
467
|
+
|
|
468
|
+
// then: garbage was rejected, loop continued to the real token
|
|
469
|
+
expect(copyAndExtractSpy).toHaveBeenCalledTimes(2)
|
|
470
|
+
expect(results).toEqual([{ token: realToken, accountType: 'work', accountTypeKnown: true }])
|
|
471
|
+
|
|
472
|
+
getPathsSpy.mockRestore()
|
|
473
|
+
copyAndExtractSpy.mockRestore()
|
|
474
|
+
cleanup()
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
// Regression for #163: browser-sourced tokens carry accountTypeKnown=false so that
|
|
478
|
+
// the auth command can probe both endpoints. The extraction loop must preserve the
|
|
479
|
+
// flag and must not dedupe an unknown-type browser token by its guessed accountType.
|
|
480
|
+
it('propagates accountTypeKnown=false for browser-sourced tokens', async () => {
|
|
481
|
+
// given: a browser Cookies path returning a valid token, guessed as work
|
|
482
|
+
const browserPath = join(workDir, 'Chrome', 'Default', 'Cookies')
|
|
483
|
+
mkdirSync(join(workDir, 'Chrome', 'Default'), { recursive: true })
|
|
484
|
+
writeFileSync(browserPath, '')
|
|
485
|
+
|
|
486
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
487
|
+
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
488
|
+
{ path: browserPath, accountType: 'work', accountTypeKnown: false },
|
|
489
|
+
])
|
|
490
|
+
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract').mockResolvedValue(mockToken)
|
|
491
|
+
|
|
492
|
+
// when
|
|
493
|
+
const results = await (winExtractor as any).extractFromCookiesDB()
|
|
494
|
+
|
|
495
|
+
// then: the flag is passed through so callers can probe
|
|
496
|
+
expect(results).toEqual([{ token: mockToken, accountType: 'work', accountTypeKnown: false }])
|
|
497
|
+
|
|
498
|
+
getPathsSpy.mockRestore()
|
|
499
|
+
copyAndExtractSpy.mockRestore()
|
|
500
|
+
cleanup()
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
// Regression for #163: when a desktop path (known=true) for 'work' already succeeded,
|
|
504
|
+
// a subsequent browser path (known=false) guessed as 'work' must still be explored —
|
|
505
|
+
// it might be a personal account misguessed as work. The dedup only kicks in for
|
|
506
|
+
// confidently labeled paths.
|
|
507
|
+
it('does not skip unknown-type path just because a known-type same-label succeeded', async () => {
|
|
508
|
+
const desktopPath = join(workDir, 'WV2Profile_tfw', 'Network', 'Cookies')
|
|
509
|
+
const browserPath = join(workDir, 'Chrome', 'Default', 'Cookies')
|
|
510
|
+
mkdirSync(join(workDir, 'WV2Profile_tfw', 'Network'), { recursive: true })
|
|
511
|
+
mkdirSync(join(workDir, 'Chrome', 'Default'), { recursive: true })
|
|
512
|
+
writeFileSync(desktopPath, '')
|
|
513
|
+
writeFileSync(browserPath, '')
|
|
514
|
+
|
|
515
|
+
const desktopToken = mockToken
|
|
516
|
+
const browserToken = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJicm93c2VyIn0.different_signature_here_abc'
|
|
517
|
+
|
|
518
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
519
|
+
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
520
|
+
{ path: desktopPath, accountType: 'work', accountTypeKnown: true },
|
|
521
|
+
{ path: browserPath, accountType: 'work', accountTypeKnown: false },
|
|
522
|
+
])
|
|
523
|
+
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract')
|
|
524
|
+
.mockResolvedValueOnce(desktopToken)
|
|
525
|
+
.mockResolvedValueOnce(browserToken)
|
|
526
|
+
|
|
527
|
+
// when
|
|
528
|
+
const results = await (winExtractor as any).extractFromCookiesDB()
|
|
529
|
+
|
|
530
|
+
// then: both tokens returned; browser token keeps accountTypeKnown=false for probing
|
|
531
|
+
expect(results).toEqual([
|
|
532
|
+
{ token: desktopToken, accountType: 'work', accountTypeKnown: true },
|
|
533
|
+
{ token: browserToken, accountType: 'work', accountTypeKnown: false },
|
|
534
|
+
])
|
|
535
|
+
|
|
536
|
+
getPathsSpy.mockRestore()
|
|
537
|
+
copyAndExtractSpy.mockRestore()
|
|
538
|
+
cleanup()
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
it('dedupes identical tokens extracted from multiple paths', async () => {
|
|
542
|
+
const path1 = join(workDir, 'Chrome', 'Default', 'Cookies')
|
|
543
|
+
const path2 = join(workDir, 'Edge', 'Default', 'Cookies')
|
|
544
|
+
mkdirSync(join(workDir, 'Chrome', 'Default'), { recursive: true })
|
|
545
|
+
mkdirSync(join(workDir, 'Edge', 'Default'), { recursive: true })
|
|
546
|
+
writeFileSync(path1, '')
|
|
547
|
+
writeFileSync(path2, '')
|
|
548
|
+
|
|
549
|
+
const winExtractor = new TeamsTokenExtractor('win32')
|
|
550
|
+
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
551
|
+
{ path: path1, accountType: 'work', accountTypeKnown: false },
|
|
552
|
+
{ path: path2, accountType: 'work', accountTypeKnown: false },
|
|
553
|
+
])
|
|
554
|
+
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract').mockResolvedValue(mockToken)
|
|
555
|
+
|
|
556
|
+
// when
|
|
557
|
+
const results = await (winExtractor as any).extractFromCookiesDB()
|
|
558
|
+
|
|
559
|
+
// then: only one result despite two paths returning the same token
|
|
560
|
+
expect(results).toHaveLength(1)
|
|
561
|
+
expect(results[0].token).toBe(mockToken)
|
|
380
562
|
|
|
381
563
|
getPathsSpy.mockRestore()
|
|
382
564
|
copyAndExtractSpy.mockRestore()
|
|
383
565
|
cleanup()
|
|
384
566
|
})
|
|
385
567
|
|
|
386
|
-
|
|
568
|
+
it('a missing path does not mark the account type as seen', async () => {
|
|
387
569
|
// given: work account has Cookies missing but Network/Cookies present
|
|
388
570
|
const workProfile = join(workDir, 'WV2Profile_tfw')
|
|
389
571
|
const workNetworkDir = join(workProfile, 'Network')
|
|
@@ -394,8 +576,8 @@ describe('TeamsTokenExtractor', () => {
|
|
|
394
576
|
|
|
395
577
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
396
578
|
const getPathsSpy = spyOn(winExtractor, 'getTeamsCookiesPaths').mockReturnValue([
|
|
397
|
-
{ path: workCookies, accountType: 'work' },
|
|
398
|
-
{ path: workNetworkCookies, accountType: 'work' },
|
|
579
|
+
{ path: workCookies, accountType: 'work', accountTypeKnown: true },
|
|
580
|
+
{ path: workNetworkCookies, accountType: 'work', accountTypeKnown: true },
|
|
399
581
|
])
|
|
400
582
|
const copyAndExtractSpy = spyOn(winExtractor as any, 'copyAndExtract').mockResolvedValue(mockToken)
|
|
401
583
|
|
|
@@ -415,7 +597,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
415
597
|
})
|
|
416
598
|
|
|
417
599
|
describe('copyAndExtract', () => {
|
|
418
|
-
|
|
600
|
+
it('attempts to copy database to temp location', async () => {
|
|
419
601
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
420
602
|
|
|
421
603
|
const copyFileSpy = spyOn(darwinExtractor as any, 'copyDatabaseToTemp').mockReturnValue('/tmp/test-cookies')
|
|
@@ -434,7 +616,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
434
616
|
cleanupSpy.mockRestore()
|
|
435
617
|
})
|
|
436
618
|
|
|
437
|
-
|
|
619
|
+
it('returns null when copy fails (file locked)', async () => {
|
|
438
620
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
439
621
|
|
|
440
622
|
const copyFileSpy = spyOn(darwinExtractor as any, 'copyDatabaseToTemp').mockImplementation(() => {
|
|
@@ -451,7 +633,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
451
633
|
|
|
452
634
|
describe('decryption', () => {
|
|
453
635
|
describe('decryptAESGCM', () => {
|
|
454
|
-
|
|
636
|
+
it('returns null for invalid encrypted data', () => {
|
|
455
637
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
456
638
|
const invalidData = Buffer.from('too_short')
|
|
457
639
|
const key = Buffer.alloc(32, 0)
|
|
@@ -460,7 +642,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
460
642
|
expect(result).toBeNull()
|
|
461
643
|
})
|
|
462
644
|
|
|
463
|
-
|
|
645
|
+
it('returns null when decryption fails', () => {
|
|
464
646
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
465
647
|
const fakeEncrypted = Buffer.concat([
|
|
466
648
|
Buffer.from('v10'),
|
|
@@ -476,7 +658,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
476
658
|
})
|
|
477
659
|
|
|
478
660
|
describe('getKeychainPassword (macOS)', () => {
|
|
479
|
-
|
|
661
|
+
it('tries multiple keychain variants', async () => {
|
|
480
662
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
481
663
|
const execSyncSpy = spyOn(darwinExtractor as any, 'execSecurityCommand')
|
|
482
664
|
.mockReturnValueOnce(null)
|
|
@@ -490,7 +672,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
490
672
|
execSyncSpy.mockRestore()
|
|
491
673
|
})
|
|
492
674
|
|
|
493
|
-
|
|
675
|
+
it('returns null when all keychain variants fail', async () => {
|
|
494
676
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
495
677
|
const execSyncSpy = spyOn(darwinExtractor as any, 'execSecurityCommand').mockReturnValue(null)
|
|
496
678
|
|
|
@@ -505,7 +687,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
505
687
|
|
|
506
688
|
describe('process management', () => {
|
|
507
689
|
describe('isTeamsRunning', () => {
|
|
508
|
-
|
|
690
|
+
it('returns true when Teams process is found', async () => {
|
|
509
691
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
510
692
|
const checkProcessRunningSpy = spyOn(darwinExtractor as any, 'checkProcessRunning').mockReturnValue(true)
|
|
511
693
|
|
|
@@ -515,7 +697,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
515
697
|
checkProcessRunningSpy.mockRestore()
|
|
516
698
|
})
|
|
517
699
|
|
|
518
|
-
|
|
700
|
+
it('returns false when no Teams process is found', async () => {
|
|
519
701
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
520
702
|
const checkProcessRunningSpy = spyOn(darwinExtractor as any, 'checkProcessRunning').mockReturnValue(false)
|
|
521
703
|
|
|
@@ -527,17 +709,17 @@ describe('TeamsTokenExtractor', () => {
|
|
|
527
709
|
})
|
|
528
710
|
|
|
529
711
|
describe('getProcessName', () => {
|
|
530
|
-
|
|
712
|
+
it('returns correct process name for macOS', () => {
|
|
531
713
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
532
714
|
expect((darwinExtractor as any).getProcessName()).toBe('Microsoft Teams')
|
|
533
715
|
})
|
|
534
716
|
|
|
535
|
-
|
|
717
|
+
it('returns correct process name for Windows', () => {
|
|
536
718
|
const winExtractor = new TeamsTokenExtractor('win32')
|
|
537
719
|
expect((winExtractor as any).getProcessName()).toBe('Teams.exe')
|
|
538
720
|
})
|
|
539
721
|
|
|
540
|
-
|
|
722
|
+
it('returns correct process name for Linux', () => {
|
|
541
723
|
const linuxExtractor = new TeamsTokenExtractor('linux')
|
|
542
724
|
expect((linuxExtractor as any).getProcessName()).toBe('teams')
|
|
543
725
|
})
|
|
@@ -545,7 +727,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
545
727
|
})
|
|
546
728
|
|
|
547
729
|
describe('SQLite extraction', () => {
|
|
548
|
-
|
|
730
|
+
it('returns null when database path does not exist', async () => {
|
|
549
731
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
550
732
|
|
|
551
733
|
const result = await (darwinExtractor as any).extractFromSQLite('/nonexistent/path')
|
|
@@ -553,7 +735,7 @@ describe('TeamsTokenExtractor', () => {
|
|
|
553
735
|
expect(result).toBeNull()
|
|
554
736
|
})
|
|
555
737
|
|
|
556
|
-
|
|
738
|
+
it('returns null when extraction throws', async () => {
|
|
557
739
|
const darwinExtractor = new TeamsTokenExtractor('darwin')
|
|
558
740
|
|
|
559
741
|
const result = await (darwinExtractor as any).extractFromSQLite('/dev/null')
|