@rudderjs/auth 0.2.0 → 0.2.1
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/README.md +63 -21
- package/boost/skills/auth-setup/SKILL.md +273 -0
- package/dist/auth-manager.d.ts +31 -1
- package/dist/auth-manager.d.ts.map +1 -1
- package/dist/auth-manager.js +53 -12
- package/dist/auth-manager.js.map +1 -1
- package/dist/gate-observers.d.ts +37 -0
- package/dist/gate-observers.d.ts.map +1 -0
- package/dist/gate-observers.js +38 -0
- package/dist/gate-observers.js.map +1 -0
- package/dist/gate.d.ts +3 -0
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +72 -15
- package/dist/gate.js.map +1 -1
- package/dist/index.d.ts +13 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +53 -39
- package/dist/index.js.map +1 -1
- package/dist/require-guest.d.ts +10 -0
- package/dist/require-guest.d.ts.map +1 -0
- package/dist/require-guest.js +25 -0
- package/dist/require-guest.js.map +1 -0
- package/dist/routes.d.ts +43 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +43 -0
- package/dist/routes.js.map +1 -0
- package/package.json +38 -8
- package/{pages/react/forgot-password/+Page.tsx → views/react/ForgotPassword.tsx} +17 -4
- package/{pages/react/login/+Page.tsx → views/react/Login.tsx} +25 -7
- package/{pages/react/register/+Page.tsx → views/react/Register.tsx} +17 -4
- package/{pages/react/reset-password/+Page.tsx → views/react/ResetPassword.tsx} +20 -5
- package/pages/react/login/+guard.ts +0 -15
- package/pages/react/register/+guard.ts +0 -15
- package/pages/solid/forgot-password/+Page.tsx +0 -62
- package/pages/solid/login/+Page.tsx +0 -66
- package/pages/solid/login/+guard.ts +0 -15
- package/pages/solid/register/+Page.tsx +0 -72
- package/pages/solid/register/+guard.ts +0 -15
- package/pages/solid/reset-password/+Page.tsx +0 -94
- package/pages/vue/forgot-password/+Page.vue +0 -60
- package/pages/vue/login/+Page.vue +0 -63
- package/pages/vue/login/+guard.ts +0 -15
- package/pages/vue/register/+Page.vue +0 -68
- package/pages/vue/register/+guard.ts +0 -15
- package/pages/vue/reset-password/+Page.vue +0 -93
package/README.md
CHANGED
|
@@ -29,51 +29,93 @@ export default {
|
|
|
29
29
|
// bootstrap/providers.ts
|
|
30
30
|
import { session } from '@rudderjs/session'
|
|
31
31
|
import { hash } from '@rudderjs/hash'
|
|
32
|
-
import {
|
|
32
|
+
import { authProvider } from '@rudderjs/auth'
|
|
33
33
|
|
|
34
34
|
export default [
|
|
35
35
|
session(configs.session),
|
|
36
36
|
hash(configs.hash),
|
|
37
|
-
|
|
37
|
+
authProvider(configs.auth),
|
|
38
38
|
]
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
> `authProvider()` is the service-provider factory.
|
|
42
|
+
> `auth()` (lowercase) is the per-request helper — see below.
|
|
43
|
+
|
|
41
44
|
## Usage
|
|
42
45
|
|
|
43
|
-
###
|
|
46
|
+
### Reading the current user
|
|
47
|
+
|
|
48
|
+
Three equivalent shapes, pick whichever reads best at the call site:
|
|
44
49
|
|
|
45
50
|
```ts
|
|
46
|
-
import { Auth } from '@rudderjs/auth'
|
|
51
|
+
import { auth, Auth } from '@rudderjs/auth'
|
|
52
|
+
|
|
53
|
+
// 1. `auth()` helper — Laravel's `auth()->user()`
|
|
54
|
+
const user = await auth().user()
|
|
55
|
+
const ok = await auth().check()
|
|
56
|
+
const user = await auth().guard('api').user() // non-default guard
|
|
57
|
+
|
|
58
|
+
// 2. `Auth` facade — same thing, static methods
|
|
59
|
+
const user = await Auth.user()
|
|
60
|
+
const ok = await Auth.check()
|
|
61
|
+
|
|
62
|
+
// 3. `req.user` — populated on every request, zero await
|
|
63
|
+
Route.get('/profile', async (req) => {
|
|
64
|
+
return { user: req.user ?? null }
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
None of these require attaching any middleware per-route. The `authProvider()`
|
|
69
|
+
service provider installs `AuthMiddleware` as a global router middleware at
|
|
70
|
+
boot, so every request has the auth context ready before your handler runs.
|
|
71
|
+
|
|
72
|
+
### Login / logout
|
|
47
73
|
|
|
48
|
-
|
|
74
|
+
```ts
|
|
75
|
+
// Attempt with credentials
|
|
49
76
|
const success = await Auth.attempt({ email, password })
|
|
50
77
|
|
|
51
|
-
// Manual login
|
|
52
|
-
Auth.login(user)
|
|
53
|
-
Auth.logout()
|
|
78
|
+
// Manual login (after a sign-up flow, social login, etc.)
|
|
79
|
+
await Auth.login(user)
|
|
54
80
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const ok = await Auth.check() // boolean
|
|
59
|
-
const no = await Auth.guest() // boolean
|
|
81
|
+
// Logout
|
|
82
|
+
await Auth.logout()
|
|
83
|
+
```
|
|
60
84
|
|
|
61
|
-
|
|
62
|
-
|
|
85
|
+
### Route protection
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { RequireAuth, RequireGuest } from '@rudderjs/auth'
|
|
89
|
+
|
|
90
|
+
// 401 if not logged in
|
|
91
|
+
Route.post('/posts', handler, [RequireAuth()])
|
|
92
|
+
|
|
93
|
+
// Bounce already-logged-in users away (e.g. /login, /register)
|
|
94
|
+
Route.get('/login', showLoginPage, [RequireGuest('/')])
|
|
63
95
|
```
|
|
64
96
|
|
|
65
|
-
###
|
|
97
|
+
### `AuthMiddleware` — advanced only
|
|
66
98
|
|
|
67
99
|
```ts
|
|
68
|
-
import { AuthMiddleware
|
|
100
|
+
import { AuthMiddleware } from '@rudderjs/auth'
|
|
101
|
+
```
|
|
69
102
|
|
|
70
|
-
|
|
71
|
-
|
|
103
|
+
**You don't normally attach this.** The `authProvider()` service provider
|
|
104
|
+
already installs `AuthMiddleware()` globally, so `req.user` and `auth()` work
|
|
105
|
+
on every route without wiring. The only time to reach for it manually is to
|
|
106
|
+
run a **non-default guard** on a specific route — the RudderJS equivalent of
|
|
107
|
+
Laravel's `->middleware('auth:api')`:
|
|
72
108
|
|
|
73
|
-
|
|
74
|
-
Route.
|
|
109
|
+
```ts
|
|
110
|
+
Route.get('/api/admin/stats', handler, [
|
|
111
|
+
AuthMiddleware('api'), // populate req.user using the 'api' guard
|
|
112
|
+
RequireAuth('api'), // 401 if not authenticated against 'api'
|
|
113
|
+
])
|
|
75
114
|
```
|
|
76
115
|
|
|
116
|
+
In normal app code you can forget `AuthMiddleware` exists — use `auth()`,
|
|
117
|
+
`Auth`, or `req.user` directly.
|
|
118
|
+
|
|
77
119
|
### Authenticatable Contract
|
|
78
120
|
|
|
79
121
|
Your User model must implement:
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: auth-setup
|
|
3
|
+
description: Setting up authentication with guards, sessions, registration, password reset, gates/policies, and vendor views in RudderJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Auth Setup
|
|
7
|
+
|
|
8
|
+
## When to use this skill
|
|
9
|
+
|
|
10
|
+
Load this skill when you need to set up authentication, configure guards, add login/register views, implement authorization gates/policies, or work with password reset and email verification.
|
|
11
|
+
|
|
12
|
+
## Key concepts
|
|
13
|
+
|
|
14
|
+
- **AuthManager**: Process-wide DI singleton that creates fresh `SessionGuard` instances per call (never cached -- prevents ghost user leaks across requests).
|
|
15
|
+
- **Guard contract**: `user()`, `check()`, `guest()`, `attempt()`, `login()`, `logout()` -- all async.
|
|
16
|
+
- **`auth()` helper**: Returns the current request's `AuthManager` via AsyncLocalStorage. Mirrors Laravel's `auth()->user()`.
|
|
17
|
+
- **Auth facade**: `Auth.user()`, `Auth.check()` etc. -- static class that proxies to `currentAuth()`.
|
|
18
|
+
- **AuthMiddleware**: Sets up the auth ALS context and populates `req.user` for every request.
|
|
19
|
+
- **RequireAuth**: Returns 401 if not authenticated.
|
|
20
|
+
- **RequireGuest**: Redirects authenticated users away from guest-only pages (login, register).
|
|
21
|
+
- **Gate/Policy**: Authorization system for checking abilities and model-level policies.
|
|
22
|
+
|
|
23
|
+
## Step-by-step
|
|
24
|
+
|
|
25
|
+
### 1. Install dependencies
|
|
26
|
+
|
|
27
|
+
Auth requires `@rudderjs/session` and `@rudderjs/hash` as peer dependencies:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @rudderjs/auth @rudderjs/session @rudderjs/hash
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Configure auth (config/auth.ts)
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { User } from '../app/Models/User.js'
|
|
37
|
+
import type { AuthConfig } from '@rudderjs/auth'
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
defaults: {
|
|
41
|
+
guard: 'web',
|
|
42
|
+
},
|
|
43
|
+
guards: {
|
|
44
|
+
web: {
|
|
45
|
+
driver: 'session',
|
|
46
|
+
provider: 'users',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
providers: {
|
|
50
|
+
users: {
|
|
51
|
+
driver: 'eloquent',
|
|
52
|
+
model: User,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
} satisfies AuthConfig
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Register the provider (bootstrap/providers.ts)
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { defaultProviders } from '@rudderjs/core'
|
|
62
|
+
// AuthProvider is auto-discovered via defaultProviders() if @rudderjs/auth is installed.
|
|
63
|
+
// It requires HashProvider and SessionProvider to boot before it.
|
|
64
|
+
export default [
|
|
65
|
+
...(await defaultProviders()),
|
|
66
|
+
// ... your app providers
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Make the User model authenticatable
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { Model, Hidden } from '@rudderjs/orm'
|
|
74
|
+
import type { Authenticatable } from '@rudderjs/auth'
|
|
75
|
+
|
|
76
|
+
export class User extends Model implements Authenticatable {
|
|
77
|
+
static fillable = ['name', 'email', 'password']
|
|
78
|
+
|
|
79
|
+
@Hidden password = ''
|
|
80
|
+
|
|
81
|
+
getAuthIdentifier(): string { return String(this.id) }
|
|
82
|
+
getAuthPassword(): string { return this.password }
|
|
83
|
+
getRememberToken(): string | null { return null }
|
|
84
|
+
setRememberToken(_token: string): void {}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. Use auth in route handlers
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { auth, Auth, RequireAuth } from '@rudderjs/auth'
|
|
92
|
+
|
|
93
|
+
// Using the auth() helper (Laravel-style)
|
|
94
|
+
router.get('/api/me', async (req, res) => {
|
|
95
|
+
const user = await auth().user()
|
|
96
|
+
if (!user) return res.status(401).json({ message: 'Unauthorized' })
|
|
97
|
+
res.json({ user })
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Using the Auth facade
|
|
101
|
+
router.get('/api/profile', async (req, res) => {
|
|
102
|
+
if (await Auth.guest()) return res.status(401).json({ message: 'Unauthorized' })
|
|
103
|
+
const user = await Auth.user()
|
|
104
|
+
res.json({ user })
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// Using RequireAuth middleware
|
|
108
|
+
router.get('/api/dashboard', RequireAuth(), async (req, res) => {
|
|
109
|
+
// req.user is guaranteed to exist here
|
|
110
|
+
res.json({ user: req.user })
|
|
111
|
+
})
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 6. Login / logout endpoints
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
router.post('/api/auth/login', async (req, res) => {
|
|
118
|
+
const { email, password } = req.body
|
|
119
|
+
const success = await auth().attempt({ email, password })
|
|
120
|
+
if (!success) {
|
|
121
|
+
return res.status(422).json({ message: 'Invalid credentials.' })
|
|
122
|
+
}
|
|
123
|
+
const user = await auth().user()
|
|
124
|
+
res.json({ user })
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
router.post('/api/auth/register', async (req, res) => {
|
|
128
|
+
const user = await User.create({
|
|
129
|
+
name: req.body.name,
|
|
130
|
+
email: req.body.email,
|
|
131
|
+
password: req.body.password, // hashed by Attribute mutator
|
|
132
|
+
})
|
|
133
|
+
await auth().login(user)
|
|
134
|
+
res.json({ user })
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
router.post('/api/auth/logout', RequireAuth(), async (req, res) => {
|
|
138
|
+
await auth().logout()
|
|
139
|
+
res.json({ message: 'Logged out.' })
|
|
140
|
+
})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 7. Set up auth views (login/register pages)
|
|
144
|
+
|
|
145
|
+
Vendor the view files into your app:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pnpm rudder vendor:publish --tag=auth-views
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This copies `@rudderjs/auth/views/react/` into `app/Views/Auth/`. Then register routes:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// routes/web.ts
|
|
155
|
+
import { Route } from '@rudderjs/router'
|
|
156
|
+
import { registerAuthRoutes } from '@rudderjs/auth/routes'
|
|
157
|
+
|
|
158
|
+
registerAuthRoutes(Route)
|
|
159
|
+
// Registers: GET /login, GET /register, GET /forgot-password, GET /reset-password
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Customize paths and view ids:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
registerAuthRoutes(Route, {
|
|
166
|
+
paths: {
|
|
167
|
+
login: '/sign-in',
|
|
168
|
+
register: '/sign-up',
|
|
169
|
+
},
|
|
170
|
+
views: {
|
|
171
|
+
login: 'auth.sign-in', // maps to app/Views/Auth/SignIn.tsx
|
|
172
|
+
register: 'auth.sign-up',
|
|
173
|
+
},
|
|
174
|
+
homeUrl: '/dashboard', // redirect destination for authenticated users
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 8. Authorization with Gates
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { Gate, Policy, AuthorizationError } from '@rudderjs/auth'
|
|
182
|
+
|
|
183
|
+
// Define abilities
|
|
184
|
+
Gate.define('manage-settings', (user) => user.role === 'admin')
|
|
185
|
+
Gate.define('edit-post', (user, post) => post.authorId === user.getAuthIdentifier())
|
|
186
|
+
|
|
187
|
+
// Check in handlers
|
|
188
|
+
if (await Gate.allows('manage-settings')) { /* ... */ }
|
|
189
|
+
if (await Gate.denies('edit-post', post)) { /* ... */ }
|
|
190
|
+
|
|
191
|
+
// Throw 403 if denied
|
|
192
|
+
await Gate.authorize('edit-post', post)
|
|
193
|
+
|
|
194
|
+
// Before callback -- runs before all checks
|
|
195
|
+
Gate.before((user, ability) => {
|
|
196
|
+
if (user.role === 'super-admin') return true // allow everything
|
|
197
|
+
return null // fall through to normal checks
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 9. Model policies
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { Policy } from '@rudderjs/auth'
|
|
205
|
+
import type { Authenticatable } from '@rudderjs/auth'
|
|
206
|
+
|
|
207
|
+
class PostPolicy extends Policy {
|
|
208
|
+
before(user: Authenticatable) {
|
|
209
|
+
if ((user as any).role === 'admin') return true
|
|
210
|
+
return null // fall through
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
view(user: Authenticatable, post: Post) {
|
|
214
|
+
return post.isPublished || post.authorId === user.getAuthIdentifier()
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
update(user: Authenticatable, post: Post) {
|
|
218
|
+
return post.authorId === user.getAuthIdentifier()
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
delete(user: Authenticatable, post: Post) {
|
|
222
|
+
return post.authorId === user.getAuthIdentifier()
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Register the policy
|
|
227
|
+
Gate.policy(Post, PostPolicy)
|
|
228
|
+
|
|
229
|
+
// Use it
|
|
230
|
+
await Gate.authorize('update', post) // auto-finds PostPolicy.update()
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 10. Email verification
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import { EnsureEmailIsVerified, verificationUrl, handleEmailVerification } from '@rudderjs/auth'
|
|
237
|
+
import type { MustVerifyEmail } from '@rudderjs/auth'
|
|
238
|
+
|
|
239
|
+
// Make user implement MustVerifyEmail
|
|
240
|
+
class User extends Model implements Authenticatable, MustVerifyEmail {
|
|
241
|
+
hasVerifiedEmail() { return this.emailVerifiedAt !== null }
|
|
242
|
+
async markEmailAsVerified() { await User.update(this.id, { emailVerifiedAt: new Date() }) }
|
|
243
|
+
getEmailForVerification() { return this.email }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Protect routes
|
|
247
|
+
router.get('/dashboard', RequireAuth(), EnsureEmailIsVerified(), handler)
|
|
248
|
+
|
|
249
|
+
// Generate verification URL (for sending in emails)
|
|
250
|
+
const url = verificationUrl(user)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 11. Password reset
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
import { PasswordBroker, MemoryTokenRepository } from '@rudderjs/auth'
|
|
257
|
+
|
|
258
|
+
const broker = new PasswordBroker(new MemoryTokenRepository())
|
|
259
|
+
// In production, implement TokenRepository backed by your database
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Examples
|
|
263
|
+
|
|
264
|
+
See `playground/config/auth.ts` for configuration, `playground/app/Models/User.ts` for the model, `playground/routes/web.ts` for route registration, and `playground/app/Views/Auth/` for vendored view files.
|
|
265
|
+
|
|
266
|
+
## Common pitfalls
|
|
267
|
+
|
|
268
|
+
- **Ghost signed-in user**: `AuthManager` must NOT cache `SessionGuard` instances. The manager is a DI singleton; cached guards leak `_user` across requests.
|
|
269
|
+
- **Provider boot order**: `HashProvider` and `SessionProvider` must boot before `AuthProvider`. With `defaultProviders()`, this is handled automatically.
|
|
270
|
+
- **Session middleware required**: Auth views require session middleware. Ensure `@rudderjs/session` is installed and its provider is registered.
|
|
271
|
+
- **View route override**: Auth view files need `export const route = '/login'` etc. so SPA navigation works correctly (URL must match Vike's route table).
|
|
272
|
+
- **POST handlers not included**: `registerAuthRoutes()` only registers GET routes for the UI pages. POST endpoints for login/register/logout are your responsibility in `routes/api.ts`.
|
|
273
|
+
- **Guard driver**: Currently only `'session'` is supported as a guard driver. API token guards are planned.
|
package/dist/auth-manager.d.ts
CHANGED
|
@@ -19,13 +19,43 @@ export declare class AuthManager {
|
|
|
19
19
|
private readonly config;
|
|
20
20
|
private readonly hashCheck;
|
|
21
21
|
private readonly getSession;
|
|
22
|
-
private readonly _guards;
|
|
23
22
|
constructor(config: AuthConfig, hashCheck: (plain: string, hashed: string) => Promise<boolean>, getSession: () => SessionStore);
|
|
23
|
+
/**
|
|
24
|
+
* Build a fresh Guard each call. We deliberately do NOT cache guards on
|
|
25
|
+
* the manager: AuthManager is a process-wide DI singleton, and a cached
|
|
26
|
+
* SessionGuard would keep `_user` populated across requests — once any
|
|
27
|
+
* request signs in, every subsequent request would see that user as
|
|
28
|
+
* "still logged in" even with an empty session. A new instance per call
|
|
29
|
+
* scopes `_user` to the local that the handler stores, which is the
|
|
30
|
+
* request-natural lifetime.
|
|
31
|
+
*/
|
|
24
32
|
guard(name?: string): Guard;
|
|
33
|
+
attempt(credentials: Record<string, unknown>, remember?: boolean): Promise<boolean>;
|
|
34
|
+
login(user: Authenticatable, remember?: boolean): Promise<void>;
|
|
35
|
+
logout(): Promise<void>;
|
|
36
|
+
user(): Promise<Authenticatable | null>;
|
|
37
|
+
id(): Promise<string | null>;
|
|
38
|
+
check(): Promise<boolean>;
|
|
39
|
+
guest(): Promise<boolean>;
|
|
25
40
|
private createProvider;
|
|
26
41
|
}
|
|
27
42
|
export declare function runWithAuth<T>(manager: AuthManager, fn: () => T): T;
|
|
28
43
|
export declare function currentAuth(): AuthManager;
|
|
44
|
+
/**
|
|
45
|
+
* Laravel-style helper — returns the current request's AuthManager.
|
|
46
|
+
*
|
|
47
|
+
* Mirrors Laravel's `auth()->user()`, `auth()->check()`, `auth()->guard('api')`.
|
|
48
|
+
* Inside an HTTP handler (after AuthMiddleware has run) you can call:
|
|
49
|
+
*
|
|
50
|
+
* await auth().user()
|
|
51
|
+
* await auth().check()
|
|
52
|
+
* await auth().guard('api').user()
|
|
53
|
+
*
|
|
54
|
+
* In non-HTTP contexts (CLI, queue, scheduler) you must still wrap the call
|
|
55
|
+
* in `runWithAuth(manager, …)` yourself — there is no request pipeline to
|
|
56
|
+
* populate the ALS context for you.
|
|
57
|
+
*/
|
|
58
|
+
export declare function auth(): AuthManager;
|
|
29
59
|
export declare class Auth {
|
|
30
60
|
private static g;
|
|
31
61
|
static guard(name: string): Guard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAgB,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKpE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;CAC9C;AAID,qBAAa,WAAW;
|
|
1
|
+
{"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAgB,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKpE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;CAC9C;AAID,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAC9D,UAAU,EAAE,MAAM,YAAY;IAGjD;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK;IAkB3B,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAInF,KAAK,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAIvC,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI5B,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzB,OAAO,CAAC,cAAc;CAavB;AAMD,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEnE;AAED,wBAAgB,WAAW,IAAI,WAAW,CAIzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,IAAI,WAAW,CAElC;AAID,qBAAa,IAAI;IACf,OAAO,CAAC,MAAM,CAAC,CAAC;IAIhB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAIjC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1F,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAI9C,MAAM,CAAC,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAGjC"}
|
package/dist/auth-manager.js
CHANGED
|
@@ -6,30 +6,54 @@ export class AuthManager {
|
|
|
6
6
|
config;
|
|
7
7
|
hashCheck;
|
|
8
8
|
getSession;
|
|
9
|
-
_guards = new Map();
|
|
10
9
|
constructor(config, hashCheck, getSession) {
|
|
11
10
|
this.config = config;
|
|
12
11
|
this.hashCheck = hashCheck;
|
|
13
12
|
this.getSession = getSession;
|
|
14
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Build a fresh Guard each call. We deliberately do NOT cache guards on
|
|
16
|
+
* the manager: AuthManager is a process-wide DI singleton, and a cached
|
|
17
|
+
* SessionGuard would keep `_user` populated across requests — once any
|
|
18
|
+
* request signs in, every subsequent request would see that user as
|
|
19
|
+
* "still logged in" even with an empty session. A new instance per call
|
|
20
|
+
* scopes `_user` to the local that the handler stores, which is the
|
|
21
|
+
* request-natural lifetime.
|
|
22
|
+
*/
|
|
15
23
|
guard(name) {
|
|
16
24
|
const guardName = name ?? this.config.defaults.guard;
|
|
17
|
-
const existing = this._guards.get(guardName);
|
|
18
|
-
if (existing)
|
|
19
|
-
return existing;
|
|
20
25
|
const guardConfig = this.config.guards[guardName];
|
|
21
26
|
if (!guardConfig)
|
|
22
27
|
throw new Error(`[RudderJS Auth] Guard "${guardName}" is not defined.`);
|
|
23
|
-
const provider = this.createProvider(guardConfig.provider);
|
|
24
|
-
let guard;
|
|
25
28
|
if (guardConfig.driver === 'session') {
|
|
26
|
-
|
|
29
|
+
const provider = this.createProvider(guardConfig.provider);
|
|
30
|
+
return new SessionGuard(provider, this.getSession());
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
throw new Error(`[RudderJS Auth] Guard driver "${guardConfig.driver}" is not supported.`);
|
|
33
|
+
}
|
|
34
|
+
// Default-guard convenience methods — match Laravel's AuthManager, which
|
|
35
|
+
// proxies these through to the default guard so `auth()->user()` works
|
|
36
|
+
// without an explicit `->guard()` call.
|
|
37
|
+
attempt(credentials, remember) {
|
|
38
|
+
return this.guard().attempt(credentials, remember);
|
|
39
|
+
}
|
|
40
|
+
login(user, remember) {
|
|
41
|
+
return this.guard().login(user, remember);
|
|
42
|
+
}
|
|
43
|
+
logout() {
|
|
44
|
+
return this.guard().logout();
|
|
45
|
+
}
|
|
46
|
+
user() {
|
|
47
|
+
return this.guard().user();
|
|
48
|
+
}
|
|
49
|
+
id() {
|
|
50
|
+
return this.guard().id();
|
|
51
|
+
}
|
|
52
|
+
check() {
|
|
53
|
+
return this.guard().check();
|
|
54
|
+
}
|
|
55
|
+
guest() {
|
|
56
|
+
return this.guard().guest();
|
|
33
57
|
}
|
|
34
58
|
createProvider(name) {
|
|
35
59
|
const providerConfig = this.config.providers[name];
|
|
@@ -52,6 +76,23 @@ export function currentAuth() {
|
|
|
52
76
|
throw new Error('[RudderJS Auth] No auth context. Use AuthMiddleware.');
|
|
53
77
|
return m;
|
|
54
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Laravel-style helper — returns the current request's AuthManager.
|
|
81
|
+
*
|
|
82
|
+
* Mirrors Laravel's `auth()->user()`, `auth()->check()`, `auth()->guard('api')`.
|
|
83
|
+
* Inside an HTTP handler (after AuthMiddleware has run) you can call:
|
|
84
|
+
*
|
|
85
|
+
* await auth().user()
|
|
86
|
+
* await auth().check()
|
|
87
|
+
* await auth().guard('api').user()
|
|
88
|
+
*
|
|
89
|
+
* In non-HTTP contexts (CLI, queue, scheduler) you must still wrap the call
|
|
90
|
+
* in `runWithAuth(manager, …)` yourself — there is no request pipeline to
|
|
91
|
+
* populate the ALS context for you.
|
|
92
|
+
*/
|
|
93
|
+
export function auth() {
|
|
94
|
+
return currentAuth();
|
|
95
|
+
}
|
|
55
96
|
// ─── Auth Facade ──────────────────────────────────────────
|
|
56
97
|
export class Auth {
|
|
57
98
|
static g(name) {
|
package/dist/auth-manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-manager.js","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,YAAY,EAAqB,MAAM,oBAAoB,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAsBrD,6DAA6D;AAE7D,MAAM,OAAO,WAAW;
|
|
1
|
+
{"version":3,"file":"auth-manager.js","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate event observers — process-wide pub/sub for authorization
|
|
3
|
+
* decisions made through `Gate.allows()`, `Gate.denies()`, and
|
|
4
|
+
* `Gate.authorize()`.
|
|
5
|
+
*
|
|
6
|
+
* Used today by `@rudderjs/telescope`'s GateCollector to record
|
|
7
|
+
* authorization checks into the dashboard.
|
|
8
|
+
*/
|
|
9
|
+
export interface GateEvent {
|
|
10
|
+
ability: string;
|
|
11
|
+
userId: string | null;
|
|
12
|
+
allowed: boolean;
|
|
13
|
+
/** What resolved the decision */
|
|
14
|
+
resolvedVia: 'ability' | 'policy' | 'before' | 'default';
|
|
15
|
+
/** Policy class name (if resolved via policy) */
|
|
16
|
+
policy?: string | undefined;
|
|
17
|
+
/** Model class name (if a model was passed) */
|
|
18
|
+
model?: string | undefined;
|
|
19
|
+
/** Duration of the check in ms */
|
|
20
|
+
duration: number;
|
|
21
|
+
}
|
|
22
|
+
export type GateObserver = (event: GateEvent) => void;
|
|
23
|
+
export declare class GateObserverRegistry {
|
|
24
|
+
private observers;
|
|
25
|
+
/** Subscribe; returns an unsubscribe function. */
|
|
26
|
+
subscribe(fn: GateObserver): () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Called by `Gate.allows()` after each authorization check.
|
|
29
|
+
* Errors thrown by observers are swallowed — observability must never
|
|
30
|
+
* break authorization.
|
|
31
|
+
*/
|
|
32
|
+
emit(event: GateEvent): void;
|
|
33
|
+
/** @internal — used in tests */
|
|
34
|
+
reset(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare const gateObservers: GateObserverRegistry;
|
|
37
|
+
//# sourceMappingURL=gate-observers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-observers.d.ts","sourceRoot":"","sources":["../src/gate-observers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAM,MAAM,CAAA;IACnB,MAAM,EAAO,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAM,OAAO,CAAA;IACpB,iCAAiC;IACjC,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;IACxD,iDAAiD;IACjD,MAAM,CAAC,EAAM,MAAM,GAAG,SAAS,CAAA;IAC/B,+CAA+C;IAC/C,KAAK,CAAC,EAAO,MAAM,GAAG,SAAS,CAAA;IAC/B,kCAAkC;IAClC,QAAQ,EAAK,MAAM,CAAA;CACpB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;AAErD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,SAAS,CAAqB;IAEtC,kDAAkD;IAClD,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM,IAAI;IAKvC;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAM5B,gCAAgC;IAChC,KAAK,IAAI,IAAI;CACd;AAQD,eAAO,MAAM,aAAa,EAAwC,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate event observers — process-wide pub/sub for authorization
|
|
3
|
+
* decisions made through `Gate.allows()`, `Gate.denies()`, and
|
|
4
|
+
* `Gate.authorize()`.
|
|
5
|
+
*
|
|
6
|
+
* Used today by `@rudderjs/telescope`'s GateCollector to record
|
|
7
|
+
* authorization checks into the dashboard.
|
|
8
|
+
*/
|
|
9
|
+
export class GateObserverRegistry {
|
|
10
|
+
observers = [];
|
|
11
|
+
/** Subscribe; returns an unsubscribe function. */
|
|
12
|
+
subscribe(fn) {
|
|
13
|
+
this.observers.push(fn);
|
|
14
|
+
return () => { this.observers = this.observers.filter(o => o !== fn); };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Called by `Gate.allows()` after each authorization check.
|
|
18
|
+
* Errors thrown by observers are swallowed — observability must never
|
|
19
|
+
* break authorization.
|
|
20
|
+
*/
|
|
21
|
+
emit(event) {
|
|
22
|
+
for (const o of this.observers) {
|
|
23
|
+
try {
|
|
24
|
+
o(event);
|
|
25
|
+
}
|
|
26
|
+
catch { /* observer errors must not break auth */ }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** @internal — used in tests */
|
|
30
|
+
reset() { this.observers = []; }
|
|
31
|
+
}
|
|
32
|
+
// Process-wide singleton, like `broadcastObservers` in `@rudderjs/broadcast`.
|
|
33
|
+
const _g = globalThis;
|
|
34
|
+
if (!_g['__rudderjs_gate_observers__']) {
|
|
35
|
+
_g['__rudderjs_gate_observers__'] = new GateObserverRegistry();
|
|
36
|
+
}
|
|
37
|
+
export const gateObservers = _g['__rudderjs_gate_observers__'];
|
|
38
|
+
//# sourceMappingURL=gate-observers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-observers.js","sourceRoot":"","sources":["../src/gate-observers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,MAAM,OAAO,oBAAoB;IACvB,SAAS,GAAmB,EAAE,CAAA;IAEtC,kDAAkD;IAClD,SAAS,CAAC,EAAgB;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvB,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA,CAAC,CAAC,CAAA;IACxE,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,KAAgB;QACnB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,yCAAyC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,KAAK,KAAW,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA,CAAC,CAAC;CACtC;AAED,8EAA8E;AAC9E,MAAM,EAAE,GAAG,UAAqC,CAAA;AAChD,IAAI,CAAC,EAAE,CAAC,6BAA6B,CAAC,EAAE,CAAC;IACvC,EAAE,CAAC,6BAA6B,CAAC,GAAG,IAAI,oBAAoB,EAAE,CAAA;AAChE,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC,6BAA6B,CAAyB,CAAA"}
|
package/dist/gate.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare class Gate {
|
|
|
28
28
|
private static _check;
|
|
29
29
|
private static findPolicy;
|
|
30
30
|
private static callPolicy;
|
|
31
|
+
/** Emit an observation event to the gate observer registry (if present). */
|
|
32
|
+
private static _emitObservation;
|
|
31
33
|
/** @internal — reset all definitions. Used for testing. */
|
|
32
34
|
static reset(): void;
|
|
33
35
|
}
|
|
@@ -38,6 +40,7 @@ declare class GateForUser {
|
|
|
38
40
|
private readonly beforeCallbacks;
|
|
39
41
|
constructor(user: Authenticatable, abilities: Map<string, AbilityCallback>, policies: Map<ModelClass, PolicyClass>, beforeCallbacks: BeforeCallback[]);
|
|
40
42
|
allows(ability: string, ...args: unknown[]): Promise<boolean>;
|
|
43
|
+
private _check;
|
|
41
44
|
denies(ability: string, ...args: unknown[]): Promise<boolean>;
|
|
42
45
|
authorize(ability: string, ...args: unknown[]): Promise<void>;
|
|
43
46
|
}
|
package/dist/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAerD,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAChG,KAAK,cAAc,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAWlI,8BAAsB,MAAM;IAC1B;;;OAGG;IACH,MAAM,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;CAClG;AAED,KAAK,WAAW,GAAG,UAAU,MAAM,CAAA;AAEnC,KAAK,UAAU,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAA;AAI1D,qBAAa,IAAI;IACf,OAAO,CAAC,MAAM,CAAC,UAAU,CAAqC;IAC9D,OAAO,CAAC,MAAM,CAAC,SAAS,CAAqC;IAC7D,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAuB;IAItD,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI/D,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAI7C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;WAM9C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;WAa7D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E;;OAEG;WACU,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1E,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW;mBAM7B,WAAW;mBASX,MAAM;IAwB3B,OAAO,CAAC,MAAM,CAAC,UAAU;mBAiBJ,UAAU;IAqB/B,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAC,gBAAgB;IA0B/B,2DAA2D;IAC3D,MAAM,CAAC,KAAK,IAAI,IAAI;CAKrB;AAID,cAAM,WAAW;IAEb,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAHf,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACvC,QAAQ,EAAE,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,EACtC,eAAe,EAAE,cAAc,EAAE;IAG9C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;YAwBrD,MAAM;IAmCd,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAKpE;AAID,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,OAAM;gBAET,OAAO,SAAiC;CAIrD"}
|