fa-mcp-sdk 0.2.174 → 0.2.182

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.
@@ -1,508 +0,0 @@
1
- /**
2
- * Примеры использования системы мультиаутентификации fa-mcp-sdk
3
- */
4
-
5
- import express from 'express';
6
- import {
7
- appConfig,
8
- createAuthMW,
9
- getMultiAuthError,
10
- checkMultiAuth,
11
- detectAuthConfiguration,
12
- logAuthConfiguration,
13
- McpServerData,
14
- CustomAuthValidator,
15
- AuthResult,
16
- } from '../../core/index.js';
17
-
18
- // ========================================================================
19
- // ПРИМЕР:
20
- // ========================================================================
21
-
22
- const app = express();
23
-
24
- // Middleware с логированием конфигурации при запуске
25
- process.env.LOG_AUTH_CONFIG = 'true';
26
- const authWithLogging = createAuthMW();
27
-
28
- app.use('/api/v2', authWithLogging);
29
-
30
- // ========================================================================
31
- // ПРИМЕР 3: КАСТОМНАЯ ЛОГИКА АУТЕНТИФИКАЦИИ
32
- // ========================================================================
33
-
34
- app.use('/api/custom', async (req, res, next) => {
35
- // Публичные эндпоинты
36
- if (req.path.startsWith('/api/custom/public')) {
37
- return next();
38
- }
39
-
40
- // Для админских эндпоинтов требуем только permanent tokens
41
- if (req.path.startsWith('/api/custom/admin')) {
42
- const token = (req.headers.authorization || '').replace(/^Bearer */, '');
43
- const auth = appConfig.webServer.auth;
44
-
45
- if (auth.permanentServerTokens.includes(token)) {
46
- return next();
47
- } else {
48
- return res.status(403).json({ error: 'Admin access required' });
49
- }
50
- }
51
-
52
- try {
53
- // Для остальных используем полную мультиаутентификацию
54
- const authError = await getMultiAuthError(req);
55
- if (authError) {
56
- res.status(authError.code).send(authError.message);
57
- return;
58
- }
59
- next();
60
- } catch {
61
- res.status(500).send('Authentication error');
62
- return;
63
- }
64
- });
65
-
66
- // ========================================================================
67
- // ПРИМЕР 4: РОУТЕР С РАЗНЫМИ УРОВНЯМИ ДОСТУПА
68
- // ========================================================================
69
-
70
- const apiRouter = express.Router();
71
-
72
- // Публичные роуты - без аутентификации
73
- apiRouter.get('/health', (req, res) => {
74
- res.json({ status: 'ok' });
75
- });
76
-
77
- // Защищенные роуты - с мультиаутентификацией
78
- apiRouter.use('/protected', authWithLogging);
79
-
80
- apiRouter.get('/protected/profile', (req, res) => {
81
- const authInfo = (req as any).authInfo;
82
- res.json({
83
- profile: {
84
- authType: authInfo.authType,
85
- username: authInfo.username || 'anonymous',
86
- permissions: getPermissionsForAuthType(authInfo.authType),
87
- },
88
- });
89
- });
90
-
91
- apiRouter.get('/protected/data', (req, res) => {
92
- const authInfo = (req as any).authInfo;
93
-
94
- // Разные данные в зависимости от типа аутентификации
95
- let data;
96
- switch (authInfo.authType) {
97
- case 'permanentServerTokens':
98
- data = { level: 'server', access: 'full' };
99
- break;
100
- case 'basic':
101
- data = { level: 'basic', access: 'limited', username: authInfo.username };
102
- break;
103
- case 'pat':
104
- data = { level: 'api', access: 'token-based' };
105
- break;
106
- case 'jwtToken':
107
- data = { level: 'jwt', access: 'custom', payload: authInfo.payload };
108
- break;
109
- default:
110
- data = { level: 'unknown', access: 'none' };
111
- }
112
-
113
- res.json({ data, authInfo: authInfo.authType });
114
- });
115
-
116
- app.use('/api/v3', apiRouter);
117
-
118
- // ========================================================================
119
- // ПРИМЕР 5: ПРОГРАММНОЕ ТЕСТИРОВАНИЕ ТОКЕНОВ
120
- // ========================================================================
121
-
122
- app.post('/api/test-token', async (req, res) => {
123
- const { token } = req.body;
124
-
125
- if (!token) {
126
- return res.status(400).json({ error: 'Token required' });
127
- }
128
-
129
- try {
130
- const result = await checkMultiAuth(req);
131
-
132
- return res.json({
133
- valid: result.success,
134
- authType: result.authType,
135
- error: result.error,
136
- username: result.username,
137
- hasPayload: !!result.payload,
138
- });
139
- } catch {
140
- return res.status(500).json({ error: 'Authentication test failed' });
141
- }
142
- });
143
-
144
- // ========================================================================
145
- // ПРИМЕР 6: MIDDLEWARE ДЛЯ РАЗНЫХ ТИПОВ API
146
- // ========================================================================
147
-
148
- // REST API - требует любую валидную аутентификацию
149
- app.use('/rest', authWithLogging);
150
-
151
- // GraphQL API - требует user-level аутентификацию (не server tokens)
152
- app.use('/graphql', async (req, res, next) => {
153
- try {
154
- const authError = await getMultiAuthError(req);
155
- if (authError) {
156
- return res.status(authError.code).send(authError.message);
157
- }
158
-
159
- const authInfo = (req as any).authInfo;
160
- if (authInfo.authType === 'permanentServerTokens') {
161
- return res.status(403).json({
162
- error: 'GraphQL API requires user authentication, server tokens not allowed',
163
- });
164
- }
165
-
166
- return next();
167
- } catch {
168
- return res.status(500).send('Authentication error');
169
- }
170
- });
171
-
172
- // WebSocket API - только JWT токены (для real-time connections)
173
- app.use('/ws', async (req, res, next) => {
174
- try {
175
- const authError = await getMultiAuthError(req);
176
- if (authError) {
177
- return res.status(authError.code).send(authError.message);
178
- }
179
-
180
- const authInfo = (req as any).authInfo;
181
- if (authInfo.authType !== 'jwtToken') {
182
- return res.status(403).json({
183
- error: 'WebSocket API requires JWT tokens for session management',
184
- });
185
- }
186
-
187
- return next();
188
- } catch {
189
- return res.status(500).send('Authentication error');
190
- }
191
- });
192
-
193
- // ========================================================================
194
- // ПРИМЕР 7: ИСПОЛЬЗОВАНИЕ CHECKCOMBIПEDAUTH С КАСТОМНОЙ ВАЛИДАЦИЕЙ
195
- // ========================================================================
196
-
197
- // Пример кастомной функции аутентификации
198
- const customAuthValidator: CustomAuthValidator = async (req): Promise<AuthResult> => {
199
- // Черный ящик для кастомной логики аутентификации
200
- const userHeader = req.headers['x-user-id'];
201
- const apiKey = req.headers['x-api-key'];
202
- const clientIP = req.headers['x-real-ip'] || req.connection?.remoteAddress;
203
-
204
- try {
205
- // Пример: проверка IP-адреса из whitelist
206
- const allowedIPs = ['127.0.0.1', '192.168.1.0/24'];
207
- if (!(await isIPAllowed(clientIP, allowedIPs))) {
208
- return { success: false, error: `IP address ${clientIP} not in whitelist` };
209
- }
210
-
211
- // Пример: проверка специального API ключа
212
- if (apiKey && userHeader) {
213
- const isValidKey = await validateApiKeyForUser(apiKey, userHeader);
214
- if (!isValidKey) {
215
- return { success: false, error: 'Invalid API key for user' };
216
- }
217
-
218
- return {
219
- success: true,
220
- authType: 'basic',
221
- username: userHeader,
222
- payload: {
223
- clientIP,
224
- apiKeyPrefix: apiKey.substring(0, 8) + '...',
225
- validatedAt: new Date().toISOString(),
226
- },
227
- };
228
- }
229
-
230
- // Пример: проверка времени работы (только рабочие часы)
231
- const now = new Date();
232
- const hour = now.getHours();
233
- const isWorkingHours = hour >= 9 && hour <= 17;
234
-
235
- if (!isWorkingHours) {
236
- return { success: false, error: 'Access only allowed during business hours (9-17)' };
237
- }
238
-
239
- // Пример: проверка заголовка User-Agent
240
- const userAgent = req.headers['user-agent'];
241
- if (userAgent?.includes('bot') || userAgent?.includes('crawler')) {
242
- return { success: false, error: 'Bots and crawlers are not allowed' };
243
- }
244
-
245
- // Разрешаем доступ с базовой информацией
246
- return {
247
- success: true,
248
- authType: 'basic',
249
- username: `guest-${clientIP}`,
250
- payload: {
251
- clientIP,
252
- userAgent,
253
- accessTime: new Date().toISOString(),
254
- businessHoursAccess: isWorkingHours,
255
- },
256
- };
257
- } catch (error) {
258
- return {
259
- success: false,
260
- error: `Custom authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`,
261
- };
262
- }
263
- };
264
-
265
- // Пример middleware, который использует combined auth
266
- const combinedAuthMiddleware = async (req: any, res: any, next: any) => {
267
- try {
268
- const result = await checkMultiAuth(req);
269
-
270
- if (!result.success) {
271
- return res.status(401).json({ error: result.error });
272
- }
273
-
274
- // Добавляем информацию об аутентификации в request
275
- req.authInfo = {
276
- authType: result.authType,
277
- username: result.username,
278
- payload: result.payload,
279
- };
280
-
281
- next();
282
- } catch {
283
- res.status(500).json({ error: 'Authentication error' });
284
- }
285
- };
286
-
287
- app.use('/api/protected-combined', combinedAuthMiddleware);
288
-
289
- app.get('/api/protected-combined/data', (req, res) => {
290
- const authInfo = (req as any).authInfo;
291
- res.json({
292
- message: 'Access granted with combined auth',
293
- auth: authInfo,
294
- timestamp: new Date().toISOString(),
295
- });
296
- });
297
-
298
- // ========================================================================
299
- // ПРИМЕР 8: КОНФИГУРАЦИЯ MCP СЕРВЕРА С КАСТОМНЫМ ВАЛИДАТОРОМ
300
- // ========================================================================
301
-
302
- // Пример того, как настроить MCP сервер с кастомным валидатором
303
- const mcpServerDataExample: McpServerData = {
304
- tools: [],
305
- toolHandler: async () => ({}),
306
- agentBrief: 'Example MCP Server with Custom Auth',
307
- agentPrompt: 'An example server demonstrating custom authentication',
308
-
309
- // Кастомный валидатор аутентификации
310
- customAuthValidator: async (req): Promise<AuthResult> => {
311
- console.log('🔐 Custom auth validator called');
312
-
313
- try {
314
- // Логика валидации может быть любой:
315
- const authHeader = req.headers.authorization;
316
- const specialToken = req.headers['x-special-token'];
317
- const clientCert = req.headers['x-client-cert'];
318
-
319
- // Пример 1: Проверка специального токена
320
- if (specialToken === 'secret-company-token-2024') {
321
- console.log('✅ Authentication via special token');
322
- return {
323
- success: true,
324
- authType: 'basic',
325
- username: 'company-user',
326
- payload: {
327
- tokenType: 'company',
328
- issuedAt: new Date().toISOString(),
329
- level: 'company-wide',
330
- },
331
- };
332
- }
333
-
334
- // Пример 2: Проверка клиентского сертификата
335
- if (clientCert && (await validateClientCertificate(clientCert))) {
336
- console.log('✅ Authentication via client certificate');
337
- return {
338
- success: true,
339
- authType: 'basic',
340
- username: 'cert-user',
341
- payload: {
342
- certificateFingerprint: clientCert.substring(0, 32) + '...',
343
- validatedAt: new Date().toISOString(),
344
- level: 'certificate-based',
345
- },
346
- };
347
- }
348
-
349
- // Пример 3: Интеграция с внешней системой аутентификации
350
- if (authHeader?.startsWith('Bearer ')) {
351
- const token = authHeader.slice(7);
352
- const isValid = await validateExternalToken(token);
353
- if (isValid) {
354
- console.log('✅ Authentication via external system');
355
- return {
356
- success: true,
357
- authType: 'basic',
358
- username: 'external-user',
359
- payload: {
360
- tokenPrefix: token.substring(0, 8) + '...',
361
- validatedAt: new Date().toISOString(),
362
- level: 'external-system',
363
- },
364
- };
365
- }
366
- }
367
-
368
- console.log('❌ Custom authentication failed');
369
- return { success: false, error: 'No valid authentication method found' };
370
- } catch (error) {
371
- console.log('❌ Custom authentication error:', error);
372
- return {
373
- success: false,
374
- error: `Custom authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`,
375
- };
376
- }
377
- },
378
- };
379
-
380
- // Утилитные функции для примеров
381
- async function isIPAllowed (ip: string, allowedIPs: string[]): Promise<boolean> {
382
- // Заглушка для проверки IP
383
- return allowedIPs.some(allowed => ip.includes(allowed.split('/')[0]!));
384
- }
385
-
386
- async function validateApiKeyForUser (apiKey: string, userId: string): Promise<boolean> {
387
- // Заглушка для проверки API ключа пользователя
388
- return apiKey.length > 20 && userId.length > 0;
389
- }
390
-
391
- async function validateClientCertificate (cert: string): Promise<boolean> {
392
- // Заглушка для проверки клиентского сертификата
393
- return cert.includes('-----BEGIN CERTIFICATE-----');
394
- }
395
-
396
- async function validateExternalToken (token: string): Promise<boolean> {
397
- // Заглушка для проверки токена во внешней системе
398
- try {
399
- // Здесь может быть HTTP запрос к внешней системе
400
- return token.length > 10;
401
- } catch {
402
- return false;
403
- }
404
- }
405
-
406
- // ========================================================================
407
- // УТИЛИТНЫЕ ФУНКЦИИ
408
- // ========================================================================
409
-
410
- function getPermissionsForAuthType (authType: string): string[] {
411
- const permissions: Record<string, string[]> = {
412
- 'permanentServerTokens': ['read', 'write', 'admin', 'server'],
413
- 'jwtToken': ['read', 'write', 'session'],
414
- 'pat': ['read', 'write', 'api'],
415
- 'basic': ['read', 'basic'],
416
- };
417
-
418
- return permissions[authType] || ['read'];
419
- }
420
-
421
- // ========================================================================
422
- // ПРИМЕР 9: ИНИЦИАЛИЗАЦИЯ С ДИАГНОСТИКОЙ
423
- // ========================================================================
424
-
425
- function initializeAuthSystem () {
426
- console.log('🔐 Initializing Multi-Authentication System...');
427
-
428
- // Диагностика конфигурации
429
- const { configured, errors } = detectAuthConfiguration();
430
-
431
- console.log('📊 Auth Configuration:');
432
- console.log(` Enabled: ${!!appConfig.webServer?.auth?.enabled}`);
433
- console.log(` Configured: ${configured.join(', ')}`);
434
-
435
- if (Object.keys(errors).length > 0) {
436
- console.warn('⚠️ Configuration Issues:');
437
- Object.entries(errors).forEach(([type, errors]) => {
438
- console.warn(` ${type}: ${(errors as string[]).join(', ')}`);
439
- });
440
- }
441
-
442
- // Логирование для отладки
443
- logAuthConfiguration();
444
-
445
- console.log('✅ Multi-Authentication System initialized successfully');
446
-
447
- return {
448
- configured: configured,
449
- errors: errors,
450
- };
451
- }
452
-
453
- // ========================================================================
454
- // ПРИМЕР 11: ТЕСТИРОВАНИЕ COMBINED AUTH
455
- // ========================================================================
456
-
457
- async function testCombinedAuth () {
458
- console.log('🧪 Testing Combined Authentication...');
459
-
460
- // Создаем тестовый запрос
461
- const mockRequest = {
462
- headers: {
463
- authorization: 'Bearer test-token',
464
- 'x-user-id': 'test-user',
465
- 'x-api-key': 'test-api-key-12345',
466
- 'user-agent': 'PostmanRuntime/7.28.0',
467
- },
468
- connection: { remoteAddress: '127.0.0.1' },
469
- };
470
-
471
- try {
472
- // @ts-ignore
473
- const result = await checkMultiAuth(mockRequest);
474
-
475
- if (result.success) {
476
- console.log('✅ Combined authentication test: PASSED');
477
- console.log(` Auth Type: ${result.authType}`);
478
- console.log(` Username: ${result.username || 'N/A'}`);
479
- } else {
480
- console.log('❌ Combined authentication test: FAILED');
481
- console.log(` Error: ${result.error}`);
482
- }
483
- } catch (error) {
484
- console.log('❌ Combined authentication test: ERROR');
485
- console.log(` Exception: ${error instanceof Error ? error.message : 'Unknown error'}`);
486
- }
487
-
488
- console.log('🧪 Combined authentication testing completed');
489
- }
490
-
491
- // ========================================================================
492
- // ЭКСПОРТ ДЛЯ ИСПОЛЬЗОВАНИЯ
493
- // ========================================================================
494
-
495
- // Экспортируем все функции и примеры для использования
496
- export {
497
- // Примеры конфигурации
498
- mcpServerDataExample,
499
- customAuthValidator,
500
- combinedAuthMiddleware,
501
-
502
- // Функции тестирования
503
- initializeAuthSystem,
504
- testCombinedAuth,
505
-
506
- // Утилиты
507
- getPermissionsForAuthType,
508
- };