lex-microsoft_teams 0.5.4 → 0.5.5
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5dd2ecc48c7eda33072b23d32d9a08947b43d51aaeba49b6b4eb46fb410e8065
|
|
4
|
+
data.tar.gz: ec8b561ede2e96afe790aad56ecc02c3491117ea26e3bbd2e78a480d214a58d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 786b4d6f2b4e3cce9fee5d61d96cb2c89f31080628d19c5e146976e9eaf3ecb6e4e8eaf76854493cfa37e6dba89721c0e6dca42e8dd657bbaac67ad84b195cf6
|
|
7
|
+
data.tar.gz: 82fc1cf2c2f31b81e7f640b5edc00be53cc976733bb7c33f3d3a68648991ad0a6979cfb2eb43f57584c48aeb7dd90542ac787e056fc44938216b7b7b9bbed41a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.5] - 2026-03-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `Hooks::Auth` hook class with `mount '/callback'` for OAuth redirect via expanded hooks system
|
|
7
|
+
- `Runners::Auth#auth_callback` method handling OAuth callback with HTML response and event emission
|
|
8
|
+
- OAuth callback now routes through `Ingress.run` for RBAC and audit support
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- OAuth callback URL moves from hardcoded `/api/oauth/microsoft_teams/callback` to `/api/hooks/lex/microsoft_teams/auth/callback`
|
|
12
|
+
|
|
3
13
|
## [0.5.4] - 2026-03-19
|
|
4
14
|
|
|
5
15
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -10,7 +10,7 @@ Legion Extension that connects LegionIO to Microsoft Teams via Graph API and Bot
|
|
|
10
10
|
|
|
11
11
|
**GitHub**: https://github.com/LegionIO/lex-microsoft_teams
|
|
12
12
|
**License**: MIT
|
|
13
|
-
**Version**: 0.5.
|
|
13
|
+
**Version**: 0.5.4
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
@@ -36,7 +36,9 @@ Legion::Extensions::MicrosoftTeams
|
|
|
36
36
|
│ ├── CacheSync # Every 5min: incremental ingest of new messages
|
|
37
37
|
│ ├── DirectChatPoller # Every 5s: polls bot DM chats via Graph API
|
|
38
38
|
│ ├── ObservedChatPoller # Every 30s: polls subscribed human conversations (compliance-gated)
|
|
39
|
-
│
|
|
39
|
+
│ ├── MessageProcessor # Subscription: consumes AMQP queue, routes by mode
|
|
40
|
+
│ ├── AuthValidator # Once: validates/restores delegated tokens on boot (2s delay)
|
|
41
|
+
│ └── TokenRefresher # Every 15min (configurable): keeps delegated tokens fresh
|
|
40
42
|
├── Transport/
|
|
41
43
|
│ ├── Exchanges/Messages # teams.messages topic exchange
|
|
42
44
|
│ ├── Queues/MessagesProcess # teams.messages.process durable queue
|
|
@@ -50,7 +52,7 @@ Legion::Extensions::MicrosoftTeams
|
|
|
50
52
|
│ ├── HighWaterMark # Per-chat message dedup via legion-cache (with in-memory fallback)
|
|
51
53
|
│ ├── PromptResolver # Layered system prompt resolution (settings -> mode -> per-conversation)
|
|
52
54
|
│ ├── SessionManager # Multi-turn LLM session lifecycle with lex-memory persistence
|
|
53
|
-
│ ├── TokenCache # In-memory OAuth token cache with pre-expiry refresh (app + delegated slots)
|
|
55
|
+
│ ├── TokenCache # In-memory OAuth token cache with pre-expiry refresh (app + delegated slots, authenticated?/previously_authenticated? predicates)
|
|
54
56
|
│ ├── SubscriptionRegistry # Conversation observation subscriptions (in-memory + lex-memory)
|
|
55
57
|
│ ├── BrowserAuth # Delegated OAuth orchestrator (PKCE, headless detection, browser launch)
|
|
56
58
|
│ └── CallbackServer # Ephemeral TCP server for OAuth redirect callback
|
|
@@ -68,6 +70,18 @@ Tokens stored in Vault (`legionio/microsoft_teams/delegated_token`) with configu
|
|
|
68
70
|
|
|
69
71
|
Key files: `Helpers::BrowserAuth` (orchestrator), `Helpers::CallbackServer` (ephemeral TCP), `Runners::Auth` (authorize_url, exchange_code, refresh_delegated_token), `Helpers::TokenCache` (delegated slot).
|
|
70
72
|
|
|
73
|
+
## Token Lifecycle (v0.5.4)
|
|
74
|
+
|
|
75
|
+
Automatic delegated token management: validate on boot, refresh on a timer, re-authenticate via browser when a previously authenticated user's token expires.
|
|
76
|
+
|
|
77
|
+
- **AuthValidator** (Once actor, 2s delay): Loads token from Vault/local file on boot, attempts refresh. If refresh fails and user previously authenticated (`previously_authenticated?` — local file exists), fires BrowserAuth. Silent for users who never opted in.
|
|
78
|
+
- **TokenRefresher** (Every actor, 15min default): Guards with `authenticated?` (live token in memory). Refreshes and persists on each tick. On failure, same re-auth logic as AuthValidator.
|
|
79
|
+
- **TokenCache predicates**: `authenticated?` = live token in `@delegated_cache`. `previously_authenticated?` = local token file exists on disk. This distinction controls auto re-auth (returning users only) vs silence (never-authenticated users).
|
|
80
|
+
|
|
81
|
+
Configuration: `settings[:microsoft_teams][:auth][:delegated][:refresh_interval]` (default 900 seconds).
|
|
82
|
+
|
|
83
|
+
Design doc: `docs/plans/2026-03-19-teams-token-lifecycle-design.md`
|
|
84
|
+
|
|
71
85
|
## AI Bot (v0.2.0)
|
|
72
86
|
|
|
73
87
|
Two operating modes, both using polling (Graph API) with AMQP-based message routing:
|
|
@@ -104,6 +118,8 @@ microsoft_teams:
|
|
|
104
118
|
tenant_id: "..."
|
|
105
119
|
client_id: "..."
|
|
106
120
|
client_secret: "vault://secret/teams/client_secret"
|
|
121
|
+
delegated:
|
|
122
|
+
refresh_interval: 900 # seconds (TokenRefresher interval)
|
|
107
123
|
bot:
|
|
108
124
|
bot_id: "28:your-bot-id"
|
|
109
125
|
direct_poll_interval: 5 # seconds
|
|
@@ -197,7 +213,7 @@ Optional framework dependencies (guarded with `defined?`, not in gemspec):
|
|
|
197
213
|
|
|
198
214
|
```bash
|
|
199
215
|
bundle install
|
|
200
|
-
bundle exec rspec #
|
|
216
|
+
bundle exec rspec # 209 specs (as of v0.5.4)
|
|
201
217
|
bundle exec rubocop # Clean
|
|
202
218
|
```
|
|
203
219
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module MicrosoftTeams
|
|
6
|
+
module Hooks
|
|
7
|
+
class Auth < Legion::Extensions::Hooks::Base
|
|
8
|
+
mount '/callback'
|
|
9
|
+
|
|
10
|
+
def route(_headers, _payload)
|
|
11
|
+
:auth_callback
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def runner_class
|
|
15
|
+
'Legion::Extensions::MicrosoftTeams::Runners::Auth'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -107,6 +107,35 @@ module Legion
|
|
|
107
107
|
{ result: response.body }
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
+
def auth_callback(code: nil, state: nil, **)
|
|
111
|
+
unless code && state
|
|
112
|
+
return {
|
|
113
|
+
result: { error: 'missing_params' },
|
|
114
|
+
response: { status: 400, content_type: 'text/html',
|
|
115
|
+
body: '<html><body><h2>Missing code or state parameter</h2></body></html>' }
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
Legion::Events.emit('microsoft_teams.oauth.callback', code: code, state: state) if defined?(Legion::Events)
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
result: { authenticated: true, code: code, state: state },
|
|
123
|
+
response: { status: 200, content_type: 'text/html',
|
|
124
|
+
body: callback_success_html }
|
|
125
|
+
}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
def callback_success_html
|
|
131
|
+
<<~HTML
|
|
132
|
+
<html><body style="font-family:sans-serif;text-align:center;padding:40px;">
|
|
133
|
+
<h2>Authentication complete</h2>
|
|
134
|
+
<p>You can close this window.</p>
|
|
135
|
+
</body></html>
|
|
136
|
+
HTML
|
|
137
|
+
end
|
|
138
|
+
|
|
110
139
|
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
111
140
|
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
112
141
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-microsoft_teams
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -91,6 +91,7 @@ files:
|
|
|
91
91
|
- lib/legion/extensions/microsoft_teams/helpers/session_manager.rb
|
|
92
92
|
- lib/legion/extensions/microsoft_teams/helpers/subscription_registry.rb
|
|
93
93
|
- lib/legion/extensions/microsoft_teams/helpers/token_cache.rb
|
|
94
|
+
- lib/legion/extensions/microsoft_teams/hooks/auth.rb
|
|
94
95
|
- lib/legion/extensions/microsoft_teams/local_cache/extractor.rb
|
|
95
96
|
- lib/legion/extensions/microsoft_teams/local_cache/record_parser.rb
|
|
96
97
|
- lib/legion/extensions/microsoft_teams/local_cache/sstable_reader.rb
|