een-api-toolkit 0.3.20 → 0.3.22

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.
Files changed (33) hide show
  1. package/.claude/agents/docs-accuracy-reviewer.md +146 -0
  2. package/.claude/agents/een-auth-agent.md +168 -0
  3. package/.claude/agents/een-devices-agent.md +294 -0
  4. package/.claude/agents/een-events-agent.md +375 -0
  5. package/.claude/agents/een-media-agent.md +256 -0
  6. package/.claude/agents/een-setup-agent.md +126 -0
  7. package/.claude/agents/een-users-agent.md +239 -0
  8. package/.claude/agents/test-runner.md +144 -0
  9. package/CHANGELOG.md +138 -30
  10. package/docs/AI-CONTEXT.md +169 -1700
  11. package/docs/ai-reference/AI-AUTH.md +288 -0
  12. package/docs/ai-reference/AI-DEVICES.md +569 -0
  13. package/docs/ai-reference/AI-EVENTS.md +1745 -0
  14. package/docs/ai-reference/AI-MEDIA.md +974 -0
  15. package/docs/ai-reference/AI-SETUP.md +267 -0
  16. package/docs/ai-reference/AI-USERS.md +255 -0
  17. package/examples/vue-event-subscriptions/package-lock.json +8 -1
  18. package/examples/vue-event-subscriptions/package.json +1 -0
  19. package/examples/vue-event-subscriptions/src/App.vue +1 -41
  20. package/examples/vue-event-subscriptions/src/composables/useHlsPlayer.ts +272 -0
  21. package/examples/vue-event-subscriptions/src/main.ts +3 -3
  22. package/examples/vue-event-subscriptions/src/stores/connection.ts +101 -0
  23. package/examples/vue-event-subscriptions/src/stores/mediaSession.ts +79 -0
  24. package/examples/vue-event-subscriptions/src/views/LiveEvents.vue +349 -88
  25. package/examples/vue-event-subscriptions/src/views/Logout.vue +6 -0
  26. package/examples/vue-event-subscriptions/src/views/Subscriptions.vue +0 -13
  27. package/examples/vue-events/package-lock.json +8 -1
  28. package/examples/vue-events/package.json +1 -0
  29. package/examples/vue-events/src/components/EventsModal.vue +269 -47
  30. package/examples/vue-events/src/composables/useHlsPlayer.ts +272 -0
  31. package/examples/vue-events/src/stores/mediaSession.ts +79 -0
  32. package/package.json +10 -2
  33. package/scripts/setup-agents.ts +116 -0
@@ -0,0 +1,288 @@
1
+ # Authentication - EEN API Toolkit
2
+
3
+ > **Version:** 0.3.22
4
+ >
5
+ > OAuth flow implementation, token management, and session handling.
6
+ > Load this document when implementing login, logout, or auth guards.
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ The toolkit uses OAuth 2.0 with a proxy server for secure token management:
13
+
14
+ 1. **User clicks login** → Redirect to EEN Identity Provider
15
+ 2. **User authenticates** → EEN redirects back with auth code
16
+ 3. **App exchanges code** → Proxy exchanges code for tokens
17
+ 4. **Refresh token stored** → Proxy keeps refresh token secure (never sent to client)
18
+ 5. **Access token returned** → Client stores short-lived access token
19
+
20
+ ---
21
+
22
+ ## Authentication Functions
23
+
24
+ ### getAuthUrl()
25
+
26
+ Generate the OAuth authorization URL. Redirect the user here to start login.
27
+
28
+ ```typescript
29
+ import { getAuthUrl } from 'een-api-toolkit'
30
+
31
+ function login() {
32
+ window.location.href = getAuthUrl()
33
+ }
34
+ ```
35
+
36
+ ### handleAuthCallback(code, state)
37
+
38
+ Handle the OAuth callback. Call this when user returns to your redirect URI.
39
+
40
+ ```typescript
41
+ import { handleAuthCallback } from 'een-api-toolkit'
42
+
43
+ const { data, error } = await handleAuthCallback(code, state)
44
+
45
+ if (error) {
46
+ console.error('Auth failed:', error.message)
47
+ return
48
+ }
49
+
50
+ // User is now authenticated
51
+ router.push('/dashboard')
52
+ ```
53
+
54
+ ### refreshToken()
55
+
56
+ Manually refresh the access token. Usually handled automatically.
57
+
58
+ ```typescript
59
+ import { refreshToken } from 'een-api-toolkit'
60
+
61
+ const { data, error } = await refreshToken()
62
+ if (error) {
63
+ // Refresh failed - redirect to login
64
+ router.push('/login')
65
+ }
66
+ ```
67
+
68
+ ### revokeToken()
69
+
70
+ Revoke the token and logout.
71
+
72
+ ```typescript
73
+ import { revokeToken } from 'een-api-toolkit'
74
+
75
+ async function logout() {
76
+ await revokeToken()
77
+ router.push('/login')
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Auth Store (useAuthStore)
84
+
85
+ Access authentication state directly:
86
+
87
+ ```typescript
88
+ import { useAuthStore } from 'een-api-toolkit'
89
+
90
+ const authStore = useAuthStore()
91
+
92
+ // Reactive state
93
+ authStore.isAuthenticated // boolean
94
+ authStore.token // Access token (or null)
95
+ authStore.baseUrl // EEN API base URL (e.g., https://c001.eagleeyenetworks.com)
96
+ authStore.sessionId // Session identifier
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Vue Router Auth Guard
102
+
103
+ Protect routes that require authentication:
104
+
105
+ ```typescript
106
+ import { useAuthStore } from 'een-api-toolkit'
107
+
108
+ router.beforeEach((to, _from, next) => {
109
+ const authStore = useAuthStore()
110
+
111
+ if (to.meta.requiresAuth && !authStore.isAuthenticated) {
112
+ next({ name: 'login' })
113
+ } else {
114
+ next()
115
+ }
116
+ })
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Component Templates
122
+
123
+ ### Login.vue
124
+
125
+ ```vue
126
+ <script setup lang="ts">
127
+ import { getAuthUrl } from 'een-api-toolkit'
128
+
129
+ function login() {
130
+ // Redirect to EEN OAuth login
131
+ window.location.href = getAuthUrl()
132
+ }
133
+ </script>
134
+
135
+ <template>
136
+ <div class="login">
137
+ <h2 data-testid="login-title">Login</h2>
138
+ <p>Click the button below to login with your Eagle Eye Networks account.</p>
139
+ <button data-testid="login-button" @click="login">Login with Eagle Eye Networks</button>
140
+ </div>
141
+ </template>
142
+ ```
143
+
144
+ ### Callback.vue
145
+
146
+ ```vue
147
+ <script setup lang="ts">
148
+ import { onMounted, ref } from 'vue'
149
+ import { useRouter } from 'vue-router'
150
+ import { handleAuthCallback } from 'een-api-toolkit'
151
+
152
+ const router = useRouter()
153
+ const error = ref<string | null>(null)
154
+ const processing = ref(true)
155
+
156
+ onMounted(async () => {
157
+ const url = new URL(window.location.href)
158
+ const code = url.searchParams.get('code')
159
+ const state = url.searchParams.get('state')
160
+ const errorParam = url.searchParams.get('error')
161
+
162
+ if (errorParam) {
163
+ error.value = `OAuth error: ${errorParam}`
164
+ processing.value = false
165
+ return
166
+ }
167
+
168
+ if (!code || !state) {
169
+ error.value = 'Missing authorization code or state parameter'
170
+ processing.value = false
171
+ return
172
+ }
173
+
174
+ const result = await handleAuthCallback(code, state)
175
+
176
+ if (result.error) {
177
+ error.value = result.error.message
178
+ processing.value = false
179
+ return
180
+ }
181
+
182
+ // Success - redirect to home
183
+ router.push('/')
184
+ })
185
+ </script>
186
+
187
+ <template>
188
+ <div class="callback">
189
+ <div v-if="processing" class="loading">
190
+ <h2>Authenticating...</h2>
191
+ <p>Please wait while we complete the login process.</p>
192
+ </div>
193
+
194
+ <div v-else-if="error" class="error-state">
195
+ <h2>Authentication Failed</h2>
196
+ <p class="error">{{ error }}</p>
197
+ <router-link to="/login">
198
+ <button>Try Again</button>
199
+ </router-link>
200
+ </div>
201
+ </div>
202
+ </template>
203
+ ```
204
+
205
+ ### Logout.vue
206
+
207
+ ```vue
208
+ <script setup lang="ts">
209
+ import { onMounted, ref } from 'vue'
210
+ import { useRouter } from 'vue-router'
211
+ import { revokeToken } from 'een-api-toolkit'
212
+
213
+ const router = useRouter()
214
+ const processing = ref(true)
215
+ const error = ref<string | null>(null)
216
+
217
+ onMounted(async () => {
218
+ const result = await revokeToken()
219
+
220
+ if (result.error) {
221
+ // Even if revoke fails, the local state is cleared
222
+ console.warn('Token revocation failed:', result.error.message)
223
+ }
224
+
225
+ processing.value = false
226
+
227
+ // Redirect to home after a short delay
228
+ setTimeout(() => {
229
+ router.push('/')
230
+ }, 2000)
231
+ })
232
+ </script>
233
+
234
+ <template>
235
+ <div class="logout">
236
+ <div v-if="processing">
237
+ <h2>Logging out...</h2>
238
+ <p class="loading">Please wait.</p>
239
+ </div>
240
+
241
+ <div v-else>
242
+ <h2>Logged Out</h2>
243
+ <p>You have been successfully logged out.</p>
244
+ <p v-if="error" class="error">Note: {{ error }}</p>
245
+ <p class="redirect">Redirecting to home page...</p>
246
+ </div>
247
+ </div>
248
+ </template>
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Token Lifecycle
254
+
255
+ | Event | Action |
256
+ |-------|--------|
257
+ | App loads | Check for existing token in storage |
258
+ | Token expires | Auto-refresh triggered (5 min before expiry) |
259
+ | Refresh fails | Clear auth state, redirect to login |
260
+ | User logs out | Revoke token, clear storage |
261
+
262
+ ---
263
+
264
+ ## Storage Strategies
265
+
266
+ ```typescript
267
+ import { getStorageStrategy, STORAGE_STRATEGY_DESCRIPTIONS } from 'een-api-toolkit'
268
+
269
+ const strategy = getStorageStrategy()
270
+ const description = STORAGE_STRATEGY_DESCRIPTIONS[strategy]
271
+ // e.g., "localStorage: persists across sessions"
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Common Auth Errors
277
+
278
+ | Error Code | Cause | Solution |
279
+ |------------|-------|----------|
280
+ | `AUTH_REQUIRED` | No valid token | Redirect to login |
281
+ | `AUTH_FAILED` | Invalid credentials | Show error, allow retry |
282
+ | `TOKEN_EXPIRED` | Token expired | Auto-refresh or re-login |
283
+
284
+ ---
285
+
286
+ ## Reference Example
287
+
288
+ See `examples/vue-users/src/views/Login.vue`, `Callback.vue`, `Logout.vue`