@aifabrix/miso-client 1.0.1 → 1.0.2
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 +372 -71
- package/dist/examples/step-3-authentication.d.ts +8 -0
- package/dist/examples/step-3-authentication.d.ts.map +1 -0
- package/dist/examples/step-3-authentication.js +45 -0
- package/dist/examples/step-3-authentication.js.map +1 -0
- package/dist/examples/step-4-rbac.d.ts +8 -0
- package/dist/examples/step-4-rbac.d.ts.map +1 -0
- package/dist/examples/step-4-rbac.js +54 -0
- package/dist/examples/step-4-rbac.js.map +1 -0
- package/dist/examples/step-5-logging.d.ts +8 -0
- package/dist/examples/step-5-logging.d.ts.map +1 -0
- package/dist/examples/step-5-logging.js +66 -0
- package/dist/examples/step-5-logging.js.map +1 -0
- package/dist/examples/step-6-audit.d.ts +8 -0
- package/dist/examples/step-6-audit.d.ts.map +1 -0
- package/dist/examples/step-6-audit.js +97 -0
- package/dist/examples/step-6-audit.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,145 +3,446 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/%40aifabrix%2Fmiso-client)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
The **AI Fabrix Miso Client SDK**
|
|
6
|
+
The **AI Fabrix Miso Client SDK** provides authentication, authorization, and logging for applications integrated with the AI Fabrix platform.
|
|
7
|
+
|
|
8
|
+
## ✨ Benefits
|
|
9
|
+
|
|
10
|
+
### 🔐 Enterprise Security
|
|
11
|
+
|
|
12
|
+
**SSO and Federated Identity**
|
|
13
|
+
- Single Sign-On (SSO) with Keycloak
|
|
14
|
+
- OAuth 2.0 and OpenID Connect (OIDC) support
|
|
15
|
+
- Multi-factor authentication (MFA) ready
|
|
16
|
+
- Social login integration (Google, Microsoft, etc.)
|
|
17
|
+
|
|
18
|
+
**Centralized Access Control**
|
|
19
|
+
- Role-based access control (RBAC)
|
|
20
|
+
- Fine-grained permissions
|
|
21
|
+
- Dynamic policy enforcement
|
|
22
|
+
- Attribute-based access control (ABAC)
|
|
23
|
+
|
|
24
|
+
**API Security**
|
|
25
|
+
- JWT token validation
|
|
26
|
+
- API key authentication
|
|
27
|
+
- Token revocation support
|
|
28
|
+
- Secure token storage
|
|
29
|
+
|
|
30
|
+
### 📊 Compliance & Audit
|
|
31
|
+
|
|
32
|
+
**ISO 27001 Compliance**
|
|
33
|
+
- Comprehensive audit trails for all user actions
|
|
34
|
+
- Data access logging and monitoring
|
|
35
|
+
- Security event tracking
|
|
36
|
+
- Accountability and non-repudiation
|
|
37
|
+
|
|
38
|
+
**Regulatory Compliance**
|
|
39
|
+
- GDPR-ready data protection
|
|
40
|
+
- HIPAA-compliant audit logging
|
|
41
|
+
- SOC 2 audit trail requirements
|
|
42
|
+
- Industry-standard security controls
|
|
43
|
+
|
|
44
|
+
**Audit Capabilities**
|
|
45
|
+
- Real-time audit event logging
|
|
46
|
+
- Immutable audit records
|
|
47
|
+
- Forensic analysis support
|
|
48
|
+
- Compliance reporting automation
|
|
49
|
+
|
|
50
|
+
### ⚡ Performance & Scalability
|
|
51
|
+
|
|
52
|
+
**Intelligent Caching**
|
|
53
|
+
- Redis-based role and permission caching
|
|
54
|
+
- Configurable cache TTL (default: 15 minutes)
|
|
55
|
+
- Automatic cache invalidation
|
|
56
|
+
- Fallback to controller when Redis unavailable
|
|
57
|
+
|
|
58
|
+
**High Availability**
|
|
59
|
+
- Automatic failover to controller
|
|
60
|
+
- Redundant infrastructure support
|
|
61
|
+
- Load balancing compatible
|
|
62
|
+
- Zero-downtime deployments
|
|
63
|
+
|
|
64
|
+
**Optimized Network**
|
|
65
|
+
- Efficient API calls with caching
|
|
66
|
+
- Batch operations support
|
|
67
|
+
- Connection pooling
|
|
68
|
+
- Minimal latency
|
|
69
|
+
|
|
70
|
+
### 🛠️ Developer Experience
|
|
71
|
+
|
|
72
|
+
**Easy Integration**
|
|
73
|
+
- Progressive activation (6-step setup)
|
|
74
|
+
- Works with any framework (Express, Next.js, NestJS, Fastify)
|
|
75
|
+
- TypeScript-first with full type definitions
|
|
76
|
+
- Browser and Node.js support
|
|
77
|
+
|
|
78
|
+
**Flexible Configuration**
|
|
79
|
+
- Environment-based configuration
|
|
80
|
+
- Support for dev, test, and production environments
|
|
81
|
+
- Docker and Kubernetes ready
|
|
82
|
+
- CI/CD friendly
|
|
83
|
+
|
|
84
|
+
**Observability**
|
|
85
|
+
- Centralized logging with correlation IDs
|
|
86
|
+
- Performance tracking and metrics
|
|
87
|
+
- Error tracking and debugging
|
|
88
|
+
- Health monitoring
|
|
7
89
|
|
|
8
|
-
|
|
90
|
+
---
|
|
9
91
|
|
|
10
|
-
|
|
11
|
-
- **🛡️ Authorization**: Role and permission-based access control
|
|
12
|
-
- **📊 Logging**: Centralized logging with audit trails and API key authentication
|
|
13
|
-
- **⚡ Caching**: Redis-based caching for improved performance
|
|
14
|
-
- **🔄 Fallback**: Automatic fallback to controller when Redis is unavailable
|
|
15
|
-
- **🔑 API Key Security**: Secure API key authentication for application logging
|
|
16
|
-
- **📱 Multi-platform**: Works in Node.js and browser environments
|
|
17
|
-
- **🔧 TypeScript**: Full TypeScript support with type definitions
|
|
92
|
+
## 🚀 Quick Start
|
|
18
93
|
|
|
19
|
-
|
|
94
|
+
Get your application secured in 6 steps.
|
|
20
95
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
96
|
+
### Step 1: Set Up Your Environment
|
|
97
|
+
|
|
98
|
+
**What you need:**
|
|
99
|
+
- Keycloak running for authentication
|
|
100
|
+
- AI Fabrix Miso Controller running
|
|
26
101
|
|
|
27
|
-
|
|
102
|
+
**First time setting up?** Use the [AI Fabrix Builder Quick Start](https://github.com/esystemsdev/aifabrix-builder/blob/main/docs/QUICK-START.md):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Start infrastructure (Postgres, Redis)
|
|
106
|
+
aifabrix up
|
|
107
|
+
|
|
108
|
+
# Install Keycloak for authentication
|
|
109
|
+
aifabrix create keycloak --port 8082 --database --template platform
|
|
110
|
+
aifabrix build keycloak
|
|
111
|
+
aifabrix run keycloak
|
|
112
|
+
|
|
113
|
+
# Install Miso Controller
|
|
114
|
+
aifabrix create miso-controller --port 3000 --database --redis --template platform
|
|
115
|
+
aifabrix build miso-controller
|
|
116
|
+
aifabrix run miso-controller
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
→ [Infrastructure Guide](https://github.com/esystemsdev/aifabrix-builder/blob/main/docs/INFRASTRUCTURE.md)
|
|
120
|
+
|
|
121
|
+
**Already have Keycloak and Controller?** Skip to Step 2.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### Step 2: Install Miso Client
|
|
28
126
|
|
|
29
127
|
```bash
|
|
30
128
|
npm install @aifabrix/miso-client
|
|
31
129
|
```
|
|
32
130
|
|
|
131
|
+
**What you get:**
|
|
132
|
+
- Authentication with Keycloak
|
|
133
|
+
- Role-based access control (RBAC)
|
|
134
|
+
- Centralized logging
|
|
135
|
+
- Redis caching for performance
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### Step 3: Activate Authentication
|
|
140
|
+
|
|
141
|
+
**What happens:** Your app validates user tokens from Keycloak.
|
|
142
|
+
|
|
33
143
|
```typescript
|
|
34
144
|
import { MisoClient } from '@aifabrix/miso-client';
|
|
35
145
|
|
|
146
|
+
// Create client
|
|
36
147
|
const client = new MisoClient({
|
|
37
148
|
controllerUrl: 'https://controller.aifabrix.ai',
|
|
38
149
|
environment: 'dev',
|
|
39
|
-
applicationKey: '
|
|
40
|
-
applicationId: '
|
|
41
|
-
apiKey: 'your-api-key', // NEW: API key for logging
|
|
42
|
-
redis: {
|
|
43
|
-
host: 'localhost',
|
|
44
|
-
port: 6379,
|
|
45
|
-
password: 'your-redis-password'
|
|
46
|
-
}
|
|
150
|
+
applicationKey: 'my-app',
|
|
151
|
+
applicationId: 'my-app-id-123',
|
|
47
152
|
});
|
|
48
153
|
|
|
49
154
|
await client.initialize();
|
|
50
155
|
|
|
51
|
-
// Validate
|
|
52
|
-
const
|
|
156
|
+
// Validate token from request
|
|
157
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
158
|
+
const isValid = await client.validateToken(token);
|
|
159
|
+
|
|
53
160
|
if (isValid) {
|
|
54
|
-
const user = await client.getUser(
|
|
55
|
-
|
|
161
|
+
const user = await client.getUser(token);
|
|
162
|
+
console.log('User:', user);
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Where to get tokens?** Users authenticate via Keycloak, then your app receives JWTs in the `Authorization` header.
|
|
167
|
+
|
|
168
|
+
→ [Complete authentication example](examples/step-3-authentication.ts)
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### Step 4: Activate RBAC (Roles)
|
|
173
|
+
|
|
174
|
+
**What happens:** Check user roles to control access. Roles are cached in Redis for performance.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Build on Step 3 - add Redis for caching
|
|
178
|
+
const client = new MisoClient({
|
|
179
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
180
|
+
environment: 'dev',
|
|
181
|
+
applicationKey: 'my-app',
|
|
182
|
+
applicationId: 'my-app-id-123',
|
|
183
|
+
redis: { host: 'localhost', port: 6379 }, // Add Redis
|
|
184
|
+
});
|
|
56
185
|
|
|
57
|
-
|
|
58
|
-
|
|
186
|
+
await client.initialize();
|
|
187
|
+
|
|
188
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
189
|
+
|
|
190
|
+
// Check if user has role
|
|
191
|
+
const isAdmin = await client.hasRole(token, 'admin');
|
|
192
|
+
const roles = await client.getRoles(token);
|
|
59
193
|
|
|
60
|
-
|
|
61
|
-
|
|
194
|
+
// Gate features by role
|
|
195
|
+
if (isAdmin) {
|
|
196
|
+
// Show admin panel
|
|
62
197
|
}
|
|
63
198
|
```
|
|
64
199
|
|
|
65
|
-
|
|
200
|
+
**Pro tip:** Without Redis, checks go to the controller. Add Redis to cache role lookups (15-minute default TTL).
|
|
66
201
|
|
|
67
|
-
|
|
202
|
+
→ [Complete RBAC example](examples/step-4-rbac.ts)
|
|
203
|
+
→ [RBAC Configuration](https://github.com/esystemsdev/aifabrix-builder/blob/main/docs/QUICK-START.md#step-3-create-your-app)
|
|
68
204
|
|
|
69
|
-
|
|
70
|
-
- **RoleService**: Manages user roles with Redis caching
|
|
71
|
-
- **PermissionService**: Handles fine-grained permissions
|
|
72
|
-
- **LoggerService**: Centralized logging and audit trails
|
|
73
|
-
- **RedisService**: Caching and queue management
|
|
205
|
+
---
|
|
74
206
|
|
|
75
|
-
|
|
207
|
+
### Step 5: Activate Logging
|
|
208
|
+
|
|
209
|
+
**What happens:** Application logs are sent to the Miso Controller with API key authentication.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
// Add API key for logging
|
|
213
|
+
const client = new MisoClient({
|
|
214
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
215
|
+
environment: 'dev',
|
|
216
|
+
applicationKey: 'my-app',
|
|
217
|
+
applicationId: 'my-app-id-123',
|
|
218
|
+
apiKey: 'dev-my-app-my-app-id-123-a1b2c3d4e5f6', // NEW: API key
|
|
219
|
+
redis: { host: 'localhost', port: 6379 },
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
await client.initialize();
|
|
223
|
+
|
|
224
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
225
|
+
const user = await client.getUser(token);
|
|
226
|
+
|
|
227
|
+
// Log messages
|
|
228
|
+
await client.log.info('User accessed dashboard', { userId: user?.id });
|
|
229
|
+
await client.log.error('Operation failed', { error: err.message });
|
|
230
|
+
await client.log.warn('Unusual activity', { details: '...' });
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**API key format:** `{environment}-{applicationKey}-{applicationId}-{randomString}`
|
|
234
|
+
|
|
235
|
+
**What happens to logs?** They're sent to the Miso Controller for centralized monitoring and analysis.
|
|
76
236
|
|
|
77
|
-
|
|
237
|
+
→ [Complete logging example](examples/step-5-logging.ts)
|
|
238
|
+
→ [Logging Reference](docs/api-reference.md#logger-service)
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### Step 6: Activate Audit
|
|
243
|
+
|
|
244
|
+
**What happens:** Create audit trails for compliance and security monitoring.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// Complete configuration
|
|
248
|
+
const client = new MisoClient({
|
|
249
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
250
|
+
environment: 'dev',
|
|
251
|
+
applicationKey: 'my-app',
|
|
252
|
+
applicationId: 'my-app-id-123',
|
|
253
|
+
apiKey: 'dev-my-app-my-app-id-123-a1b2c3d4e5f6',
|
|
254
|
+
redis: { host: 'localhost', port: 6379, password: 'optional' },
|
|
255
|
+
logLevel: 'info',
|
|
256
|
+
cache: { roleTTL: 900, permissionTTL: 900 },
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
await client.initialize();
|
|
260
|
+
|
|
261
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
262
|
+
const isValid = await client.validateToken(token);
|
|
263
|
+
const canEdit = await client.hasPermission(token, 'edit:content');
|
|
264
|
+
|
|
265
|
+
// Audit: User actions
|
|
266
|
+
await client.log.audit('user.login', 'authentication', {
|
|
267
|
+
userId: user?.id,
|
|
268
|
+
ip: req.ip,
|
|
269
|
+
userAgent: req.headers['user-agent'],
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Audit: Content changes
|
|
273
|
+
await client.log.audit('post.created', 'content', {
|
|
274
|
+
userId: user?.id,
|
|
275
|
+
postId: 'post-123',
|
|
276
|
+
postTitle: req.body.title,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Audit: Permission checks
|
|
280
|
+
await client.log.audit('access.denied', 'authorization', {
|
|
281
|
+
userId: user?.id,
|
|
282
|
+
requiredPermission: 'edit:content',
|
|
283
|
+
resource: 'posts',
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**What to audit:** Login/logout, permission checks, content creation/deletion, role changes, sensitive operations.
|
|
288
|
+
|
|
289
|
+
→ [Complete audit example](examples/step-6-audit.ts)
|
|
290
|
+
→ [Best Practices](docs/getting-started.md#common-patterns)
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## 🔧 Configuration
|
|
78
295
|
|
|
79
296
|
```typescript
|
|
80
297
|
interface MisoClientConfig {
|
|
81
|
-
controllerUrl: string;
|
|
82
|
-
environment: 'dev' | 'tst' | 'pro'; // Environment
|
|
83
|
-
applicationKey: string;
|
|
84
|
-
applicationId: string;
|
|
85
|
-
apiKey?: string;
|
|
86
|
-
redis?: RedisConfig;
|
|
298
|
+
controllerUrl: string; // Required: Controller URL
|
|
299
|
+
environment: 'dev' | 'tst' | 'pro'; // Required: Environment
|
|
300
|
+
applicationKey: string; // Required: App identifier
|
|
301
|
+
applicationId: string; // Required: App GUID
|
|
302
|
+
apiKey?: string; // Optional: For logging
|
|
303
|
+
redis?: RedisConfig; // Optional: For caching
|
|
87
304
|
logLevel?: 'debug' | 'info' | 'warn' | 'error';
|
|
88
305
|
cache?: {
|
|
89
|
-
roleTTL?: number;
|
|
90
|
-
permissionTTL?: number;
|
|
306
|
+
roleTTL?: number; // Role cache TTL (default: 900s)
|
|
307
|
+
permissionTTL?: number; // Permission cache TTL (default: 900s)
|
|
91
308
|
};
|
|
92
309
|
}
|
|
93
310
|
```
|
|
94
311
|
|
|
312
|
+
→ [Complete Configuration Reference](docs/configuration.md)
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 📚 Documentation
|
|
317
|
+
|
|
318
|
+
- **[Getting Started](docs/getting-started.md)** - Detailed setup guide
|
|
319
|
+
- **[API Reference](docs/api-reference.md)** - Complete API documentation
|
|
320
|
+
- **[Configuration](docs/configuration.md)** - Configuration options
|
|
321
|
+
- **[Examples](docs/examples.md)** - Framework-specific examples
|
|
322
|
+
- **[Troubleshooting](docs/troubleshooting.md)** - Common issues and solutions
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 🏗️ Architecture
|
|
327
|
+
|
|
328
|
+
The SDK consists of five core services:
|
|
329
|
+
|
|
330
|
+
- **AuthService** - Token validation and user authentication
|
|
331
|
+
- **RoleService** - Role management with Redis caching
|
|
332
|
+
- **PermissionService** - Fine-grained permissions
|
|
333
|
+
- **LoggerService** - Centralized logging with API key authentication
|
|
334
|
+
- **RedisService** - Caching and queue management (optional)
|
|
335
|
+
|
|
336
|
+
→ [Architecture Details](docs/api-reference.md#architecture)
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
95
340
|
## 🌐 Environments
|
|
96
341
|
|
|
97
342
|
The SDK supports three environments:
|
|
98
343
|
|
|
99
344
|
- **`dev`** - Development environment
|
|
100
|
-
- **`tst`** - Test environment
|
|
345
|
+
- **`tst`** - Test environment
|
|
101
346
|
- **`pro`** - Production environment
|
|
102
347
|
|
|
103
|
-
|
|
348
|
+
Each environment uses different controller endpoints and API keys.
|
|
104
349
|
|
|
105
|
-
|
|
350
|
+
---
|
|
106
351
|
|
|
107
|
-
|
|
108
|
-
|
|
352
|
+
## 💡 Next Steps
|
|
353
|
+
|
|
354
|
+
### Learn More
|
|
355
|
+
- [Express.js Middleware](docs/examples.md#expressjs-middleware) - Protect API routes
|
|
356
|
+
- [React Authentication](docs/examples.md#react-authentication) - Frontend auth
|
|
357
|
+
- [NestJS Guards](docs/examples.md#nestjs-guards) - Decorator-based auth
|
|
358
|
+
- [Error Handling](docs/examples.md#error-handling) - Best practices
|
|
359
|
+
|
|
360
|
+
### Common Tasks
|
|
361
|
+
|
|
362
|
+
**Add authentication middleware:**
|
|
363
|
+
```typescript
|
|
364
|
+
app.use(async (req, res, next) => {
|
|
365
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
366
|
+
const isValid = await client.validateToken(token);
|
|
367
|
+
if (isValid) {
|
|
368
|
+
req.user = await client.getUser(token);
|
|
369
|
+
}
|
|
370
|
+
next();
|
|
371
|
+
});
|
|
109
372
|
```
|
|
110
373
|
|
|
111
|
-
|
|
374
|
+
**Protect routes by role:**
|
|
375
|
+
```typescript
|
|
376
|
+
app.get('/admin', async (req, res) => {
|
|
377
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
378
|
+
const isAdmin = await client.hasRole(token, 'admin');
|
|
379
|
+
if (!isAdmin) return res.status(403).json({ error: 'Forbidden' });
|
|
380
|
+
// Admin only code
|
|
381
|
+
});
|
|
382
|
+
```
|
|
112
383
|
|
|
384
|
+
**Use environment variables:**
|
|
113
385
|
```bash
|
|
114
|
-
|
|
386
|
+
MISO_CONTROLLER_URL=https://controller.aifabrix.ai
|
|
387
|
+
MISO_ENVIRONMENT=dev
|
|
388
|
+
MISO_APPLICATION_KEY=my-app
|
|
389
|
+
MISO_APPLICATION_ID=my-app-id-123
|
|
390
|
+
MISO_API_KEY=dev-my-app-my-app-id-123-a1b2c3d4e5f6
|
|
391
|
+
REDIS_HOST=localhost
|
|
392
|
+
REDIS_PORT=6379
|
|
115
393
|
```
|
|
116
394
|
|
|
117
|
-
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## 🐛 Troubleshooting
|
|
398
|
+
|
|
399
|
+
**"Cannot connect to controller"**
|
|
400
|
+
→ Verify `controllerUrl` is correct and accessible
|
|
401
|
+
→ Check network connectivity
|
|
402
|
+
|
|
403
|
+
**"Redis connection failed"**
|
|
404
|
+
→ SDK falls back to controller-only mode (slower but works)
|
|
405
|
+
→ Fix: `aifabrix up` to start Redis
|
|
406
|
+
|
|
407
|
+
**"Invalid API key for logging"**
|
|
408
|
+
→ Check API key format: `{environment}-{applicationKey}-{applicationId}-{randomString}`
|
|
409
|
+
→ Verify key is configured in controller
|
|
410
|
+
|
|
411
|
+
**"Token validation fails"**
|
|
412
|
+
→ Ensure Keycloak is running and configured correctly
|
|
413
|
+
→ Verify token is from correct Keycloak instance
|
|
414
|
+
|
|
415
|
+
→ [More Help](docs/troubleshooting.md)
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## 📦 Installation
|
|
118
420
|
|
|
119
421
|
```bash
|
|
422
|
+
# NPM
|
|
423
|
+
npm install @aifabrix/miso-client
|
|
424
|
+
|
|
425
|
+
# Yarn
|
|
426
|
+
yarn add @aifabrix/miso-client
|
|
427
|
+
|
|
428
|
+
# PNPM
|
|
120
429
|
pnpm add @aifabrix/miso-client
|
|
121
430
|
```
|
|
122
431
|
|
|
432
|
+
---
|
|
433
|
+
|
|
123
434
|
## 🔗 Links
|
|
124
435
|
|
|
125
436
|
- **GitHub Repository**: [https://github.com/esystemsdev/aifabrix-miso-client](https://github.com/esystemsdev/aifabrix-miso-client)
|
|
126
|
-
- **Documentation**: [https://github.com/esystemsdev/aifabrix-
|
|
437
|
+
- **Builder Documentation**: [https://github.com/esystemsdev/aifabrix-builder](https://github.com/esystemsdev/aifabrix-builder)
|
|
127
438
|
- **Issues**: [https://github.com/esystemsdev/aifabrix-miso-client/issues](https://github.com/esystemsdev/aifabrix-miso-client/issues)
|
|
128
439
|
|
|
440
|
+
---
|
|
441
|
+
|
|
129
442
|
## 📄 License
|
|
130
443
|
|
|
131
444
|
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
132
445
|
|
|
133
|
-
## 🤝 Contributing
|
|
134
|
-
|
|
135
|
-
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
|
|
136
|
-
|
|
137
|
-
## 📞 Support
|
|
138
|
-
|
|
139
|
-
For support and questions:
|
|
140
|
-
|
|
141
|
-
- **Email**: <support@esystemsnordic.com>
|
|
142
|
-
- **Documentation**: [https://github.com/esystemsdev/aifabrix-miso-client](https://github.com/esystemsdev/aifabrix-miso-client)
|
|
143
|
-
- **GitHub Issues**: [https://github.com/esystemsdev/aifabrix-miso-client/issues](https://github.com/esystemsdev/aifabrix-miso-client/issues)
|
|
144
|
-
|
|
145
446
|
---
|
|
146
447
|
|
|
147
448
|
**Made with ❤️ by eSystems Nordic Ltd.**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-3-authentication.d.ts","sourceRoot":"","sources":["../../examples/step-3-authentication.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iBAAe,qBAAqB,kBAoCnC;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Step 3: Activate Authentication
|
|
4
|
+
*
|
|
5
|
+
* Basic token validation to verify user identity.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.authenticationExample = authenticationExample;
|
|
9
|
+
const index_1 = require("../src/index");
|
|
10
|
+
async function authenticationExample() {
|
|
11
|
+
// Create client with controller configuration
|
|
12
|
+
const client = new index_1.MisoClient({
|
|
13
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
14
|
+
environment: 'dev',
|
|
15
|
+
applicationKey: 'my-app',
|
|
16
|
+
applicationId: 'my-app-id-123',
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
// Initialize the client
|
|
20
|
+
await client.initialize();
|
|
21
|
+
console.log('✅ Client initialized successfully');
|
|
22
|
+
// Get token from your application (e.g., from HTTP request header)
|
|
23
|
+
// In real usage: const token = req.headers.authorization?.replace('Bearer ', '');
|
|
24
|
+
const token = 'your-jwt-token-here';
|
|
25
|
+
// Validate the token
|
|
26
|
+
const isValid = await client.validateToken(token);
|
|
27
|
+
if (isValid) {
|
|
28
|
+
console.log('✅ Token is valid');
|
|
29
|
+
// Get user information
|
|
30
|
+
const user = await client.getUser(token);
|
|
31
|
+
console.log('👤 User:', user);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log('❌ Token is invalid');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error('❌ Authentication error:', error);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
// Clean up connections
|
|
42
|
+
await client.disconnect();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=step-3-authentication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-3-authentication.js","sourceRoot":"","sources":["../../examples/step-3-authentication.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA0CM,sDAAqB;AAxC9B,wCAA0C;AAE1C,KAAK,UAAU,qBAAqB;IAClC,8CAA8C;IAC9C,MAAM,MAAM,GAAG,IAAI,kBAAU,CAAC;QAC5B,aAAa,EAAE,gCAAgC;QAC/C,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,QAAQ;QACxB,aAAa,EAAE,eAAe;KAC/B,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAEjD,mEAAmE;QACnE,kFAAkF;QAClF,MAAM,KAAK,GAAG,qBAAqB,CAAC;QAEpC,qBAAqB;QACrB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAElD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAEhC,uBAAuB;YACvB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;YAAS,CAAC;QACT,uBAAuB;QACvB,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-4-rbac.d.ts","sourceRoot":"","sources":["../../examples/step-4-rbac.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iBAAe,WAAW,kBAiDzB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Step 4: Activate RBAC (Role-Based Access Control)
|
|
4
|
+
*
|
|
5
|
+
* Check user roles and enforce access control.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.rbacExample = rbacExample;
|
|
9
|
+
const index_1 = require("../src/index");
|
|
10
|
+
async function rbacExample() {
|
|
11
|
+
// Create client (same as Step 3)
|
|
12
|
+
const client = new index_1.MisoClient({
|
|
13
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
14
|
+
environment: 'dev',
|
|
15
|
+
applicationKey: 'my-app',
|
|
16
|
+
applicationId: 'my-app-id-123',
|
|
17
|
+
redis: {
|
|
18
|
+
host: 'localhost',
|
|
19
|
+
port: 6379,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
try {
|
|
23
|
+
await client.initialize();
|
|
24
|
+
console.log('✅ Client initialized with Redis caching');
|
|
25
|
+
const token = 'your-jwt-token-here';
|
|
26
|
+
// Validate token (from Step 3)
|
|
27
|
+
const isValid = await client.validateToken(token);
|
|
28
|
+
if (!isValid) {
|
|
29
|
+
console.log('❌ Token is invalid');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// NEW: Get user roles
|
|
33
|
+
const roles = await client.getRoles(token);
|
|
34
|
+
console.log('🔑 User roles:', roles);
|
|
35
|
+
// NEW: Check specific role
|
|
36
|
+
const isAdmin = await client.hasRole(token, 'admin');
|
|
37
|
+
console.log('👑 Is admin:', isAdmin);
|
|
38
|
+
// NEW: Check multiple roles (user needs any of these)
|
|
39
|
+
const canManage = await client.hasAnyRole(token, ['admin', 'manager']);
|
|
40
|
+
console.log('⚙️ Can manage:', canManage);
|
|
41
|
+
// Example: Gate a feature based on role
|
|
42
|
+
if (isAdmin) {
|
|
43
|
+
console.log('🔐 Admin feature unlocked');
|
|
44
|
+
// Show admin dashboard, etc.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('❌ RBAC error:', error);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await client.disconnect();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=step-4-rbac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-4-rbac.js","sourceRoot":"","sources":["../../examples/step-4-rbac.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAuDM,kCAAW;AArDpB,wCAA0C;AAE1C,KAAK,UAAU,WAAW;IACxB,iCAAiC;IACjC,MAAM,MAAM,GAAG,IAAI,kBAAU,CAAC;QAC5B,aAAa,EAAE,gCAAgC;QAC/C,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,QAAQ;QACxB,aAAa,EAAE,eAAe;QAC9B,KAAK,EAAE;YACL,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,IAAI;SACX;KACF,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QAEvD,MAAM,KAAK,GAAG,qBAAqB,CAAC;QAEpC,+BAA+B;QAC/B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAErC,2BAA2B;QAC3B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAErC,sDAAsD;QACtD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAEzC,wCAAwC;QACxC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,6BAA6B;QAC/B,CAAC;IAEH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-5-logging.d.ts","sourceRoot":"","sources":["../../examples/step-5-logging.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iBAAe,cAAc,kBAuD5B;AAQD,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Step 5: Activate Logging
|
|
4
|
+
*
|
|
5
|
+
* Send application logs to the AI Fabrix controller.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.loggingExample = loggingExample;
|
|
9
|
+
const index_1 = require("../src/index");
|
|
10
|
+
async function loggingExample() {
|
|
11
|
+
const client = new index_1.MisoClient({
|
|
12
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
13
|
+
environment: 'dev',
|
|
14
|
+
applicationKey: 'my-app',
|
|
15
|
+
applicationId: 'my-app-id-123',
|
|
16
|
+
apiKey: 'dev-my-app-my-app-id-123-a1b2c3d4e5f6', // Required for logging
|
|
17
|
+
redis: {
|
|
18
|
+
host: 'localhost',
|
|
19
|
+
port: 6379,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
try {
|
|
23
|
+
await client.initialize();
|
|
24
|
+
const token = 'your-jwt-token-here';
|
|
25
|
+
// Validate token and get user (Steps 3-4)
|
|
26
|
+
const isValid = await client.validateToken(token);
|
|
27
|
+
if (!isValid)
|
|
28
|
+
return;
|
|
29
|
+
const user = await client.getUser(token);
|
|
30
|
+
// NEW: Log informational messages
|
|
31
|
+
await client.log.info('User accessed dashboard', {
|
|
32
|
+
userId: user?.id,
|
|
33
|
+
username: user?.username,
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
});
|
|
36
|
+
// NEW: Log errors
|
|
37
|
+
try {
|
|
38
|
+
// Some operation that might fail
|
|
39
|
+
await performOperation();
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
await client.log.error('Operation failed', {
|
|
43
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
44
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
45
|
+
userId: user?.id,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// NEW: Use debug for detailed diagnostic information
|
|
49
|
+
await client.log.debug('Processing user request', {
|
|
50
|
+
userId: user?.id,
|
|
51
|
+
requestDetails: '...',
|
|
52
|
+
});
|
|
53
|
+
console.log('📊 Logs sent to controller');
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('❌ Logging error:', error);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await client.disconnect();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function performOperation() {
|
|
63
|
+
// Your application logic
|
|
64
|
+
}
|
|
65
|
+
let someCondition = false;
|
|
66
|
+
//# sourceMappingURL=step-5-logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-5-logging.js","sourceRoot":"","sources":["../../examples/step-5-logging.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAmEM,wCAAc;AAjEvB,wCAA0C;AAE1C,KAAK,UAAU,cAAc;IAC3B,MAAM,MAAM,GAAG,IAAI,kBAAU,CAAC;QAC5B,aAAa,EAAE,gCAAgC;QAC/C,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,QAAQ;QACxB,aAAa,EAAE,eAAe;QAC9B,MAAM,EAAE,uCAAuC,EAAE,uBAAuB;QACxE,KAAK,EAAE;YACL,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,IAAI;SACX;KACF,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,qBAAqB,CAAC;QAEpC,0CAA0C;QAC1C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEzC,kCAAkC;QAClC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE;YAC/C,MAAM,EAAE,IAAI,EAAE,EAAE;YAChB,QAAQ,EAAE,IAAI,EAAE,QAAQ;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QAEH,kBAAkB;QAClB,IAAI,CAAC;YACH,iCAAiC;YACjC,MAAM,gBAAgB,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE;gBACzC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;gBAC/D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;gBACvD,MAAM,EAAE,IAAI,EAAE,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;QAED,qDAAqD;QACrD,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE;YAChD,MAAM,EAAE,IAAI,EAAE,EAAE;YAChB,cAAc,EAAE,KAAK;SACtB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB;IAC7B,yBAAyB;AAC3B,CAAC;AAED,IAAI,aAAa,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-6-audit.d.ts","sourceRoot":"","sources":["../../examples/step-6-audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iBAAe,eAAe,kBAgG7B;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Step 6: Activate Audit
|
|
4
|
+
*
|
|
5
|
+
* Complete example with authentication, RBAC, logging, and audit trails.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.completeExample = completeExample;
|
|
9
|
+
const index_1 = require("../src/index");
|
|
10
|
+
async function completeExample() {
|
|
11
|
+
const client = new index_1.MisoClient({
|
|
12
|
+
controllerUrl: 'https://controller.aifabrix.ai',
|
|
13
|
+
environment: 'dev',
|
|
14
|
+
applicationKey: 'my-app',
|
|
15
|
+
applicationId: 'my-app-id-123',
|
|
16
|
+
apiKey: 'dev-my-app-my-app-id-123-a1b2c3d4e5f6',
|
|
17
|
+
redis: {
|
|
18
|
+
host: 'localhost',
|
|
19
|
+
port: 6379,
|
|
20
|
+
password: 'your-redis-password',
|
|
21
|
+
},
|
|
22
|
+
logLevel: 'info',
|
|
23
|
+
cache: {
|
|
24
|
+
roleTTL: 900, // 15 minutes
|
|
25
|
+
permissionTTL: 900, // 15 minutes
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
try {
|
|
29
|
+
await client.initialize();
|
|
30
|
+
console.log('✅ Client fully configured');
|
|
31
|
+
const token = 'your-jwt-token-here';
|
|
32
|
+
// Step 3: Authentication
|
|
33
|
+
const isValid = await client.validateToken(token);
|
|
34
|
+
if (!isValid) {
|
|
35
|
+
await client.log.audit('access.denied', 'authentication', {
|
|
36
|
+
reason: 'Invalid token',
|
|
37
|
+
ip: '192.168.1.1',
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const user = await client.getUser(token);
|
|
42
|
+
// Step 4: RBAC
|
|
43
|
+
const canEdit = await client.hasPermission(token, 'edit:content');
|
|
44
|
+
if (!canEdit) {
|
|
45
|
+
await client.log.audit('access.denied', 'authorization', {
|
|
46
|
+
userId: user?.id,
|
|
47
|
+
action: 'edit_content',
|
|
48
|
+
resource: 'posts',
|
|
49
|
+
});
|
|
50
|
+
console.log('❌ Insufficient permissions');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Step 5: Logging
|
|
54
|
+
await client.log.info('User logged in successfully', {
|
|
55
|
+
userId: user?.id,
|
|
56
|
+
username: user?.username,
|
|
57
|
+
email: user?.email,
|
|
58
|
+
});
|
|
59
|
+
// Step 6: Audit Trail - Log important user actions
|
|
60
|
+
await client.log.audit('user.login', 'authentication', {
|
|
61
|
+
userId: user?.id,
|
|
62
|
+
ip: '192.168.1.1',
|
|
63
|
+
userAgent: 'Mozilla/5.0...',
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
});
|
|
66
|
+
// Audit example: Content changes
|
|
67
|
+
await client.log.audit('post.created', 'content', {
|
|
68
|
+
userId: user?.id,
|
|
69
|
+
postId: 'post-123',
|
|
70
|
+
postTitle: 'My New Post',
|
|
71
|
+
category: 'technology',
|
|
72
|
+
});
|
|
73
|
+
// Audit example: Permission checks
|
|
74
|
+
await client.log.audit('role.checked', 'authorization', {
|
|
75
|
+
userId: user?.id,
|
|
76
|
+
checkedRole: 'admin',
|
|
77
|
+
result: 'granted',
|
|
78
|
+
});
|
|
79
|
+
// Audit example: Sensitive operations
|
|
80
|
+
await client.log.audit('user.deleted', 'administration', {
|
|
81
|
+
userId: user?.id,
|
|
82
|
+
deletedUserId: 'user-456',
|
|
83
|
+
reason: 'Policy violation',
|
|
84
|
+
});
|
|
85
|
+
console.log('✅ Complete flow: Auth + RBAC + Logging + Audit');
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
await client.log.error('Application error', {
|
|
89
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
90
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
await client.disconnect();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=step-6-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-6-audit.js","sourceRoot":"","sources":["../../examples/step-6-audit.ts"],"names":[],"mappings":"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"}
|