fa-mcp-sdk 0.2.121 → 0.2.125

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 (97) hide show
  1. package/bin/fa-mcp.js +1 -0
  2. package/cli-template/config/_local.yaml +21 -1
  3. package/cli-template/config/custom-environment-variables.yaml +11 -1
  4. package/cli-template/config/default.yaml +11 -1
  5. package/cli-template/fa-mcp-sdk-spec.md +385 -2
  6. package/cli-template/package.json +72 -73
  7. package/cli-template/src/_examples/custom-basic-auth-example.ts +252 -0
  8. package/cli-template/src/_examples/multi-auth-examples.ts +333 -0
  9. package/cli-template/src/custom-resources.ts +1 -0
  10. package/cli-template/yarn.lock +6375 -0
  11. package/dist/core/_types_/TNtlm.d.ts +5 -0
  12. package/dist/core/_types_/TNtlm.d.ts.map +1 -0
  13. package/dist/core/_types_/TNtlm.js +2 -0
  14. package/dist/core/_types_/TNtlm.js.map +1 -0
  15. package/dist/core/_types_/config.d.ts +88 -0
  16. package/dist/core/_types_/config.d.ts.map +1 -0
  17. package/dist/core/_types_/config.js +2 -0
  18. package/dist/core/_types_/config.js.map +1 -0
  19. package/dist/core/_types_/types.d.ts +8 -0
  20. package/dist/core/_types_/types.d.ts.map +1 -1
  21. package/dist/core/{token/token-core.d.ts → auth/jwt-validation.d.ts} +2 -2
  22. package/dist/core/auth/jwt-validation.d.ts.map +1 -0
  23. package/dist/core/{token/token-core.js → auth/jwt-validation.js} +4 -4
  24. package/dist/core/auth/jwt-validation.js.map +1 -0
  25. package/dist/core/auth/middleware.d.ts +47 -0
  26. package/dist/core/auth/middleware.d.ts.map +1 -0
  27. package/dist/core/{token/token-auth.js → auth/middleware.js} +114 -2
  28. package/dist/core/auth/middleware.js.map +1 -0
  29. package/dist/core/auth/multi-auth.d.ts +27 -0
  30. package/dist/core/auth/multi-auth.d.ts.map +1 -0
  31. package/dist/core/auth/multi-auth.js +300 -0
  32. package/dist/core/auth/multi-auth.js.map +1 -0
  33. package/dist/core/auth/token-generator/html.d.ts.map +1 -0
  34. package/dist/core/{token/gen-token-app → auth/token-generator}/html.js +2 -2
  35. package/dist/core/auth/token-generator/html.js.map +1 -0
  36. package/dist/core/auth/token-generator/ntlm-auth-options.d.ts.map +1 -0
  37. package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-auth-options.js +1 -1
  38. package/dist/core/auth/token-generator/ntlm-auth-options.js.map +1 -0
  39. package/dist/core/auth/token-generator/ntlm-domain-config.d.ts.map +1 -0
  40. package/dist/core/auth/token-generator/ntlm-domain-config.js.map +1 -0
  41. package/dist/core/auth/token-generator/ntlm-integration.d.ts.map +1 -0
  42. package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-integration.js +4 -4
  43. package/dist/core/auth/token-generator/ntlm-integration.js.map +1 -0
  44. package/dist/core/auth/token-generator/ntlm-session-storage.d.ts.map +1 -0
  45. package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-session-storage.js +1 -1
  46. package/dist/core/auth/token-generator/ntlm-session-storage.js.map +1 -0
  47. package/dist/core/auth/token-generator/ntlm-templates.d.ts.map +1 -0
  48. package/dist/core/auth/token-generator/ntlm-templates.js.map +1 -0
  49. package/dist/core/{token/gen-token-app/gen-token-server.d.ts → auth/token-generator/server.d.ts} +1 -1
  50. package/dist/core/auth/token-generator/server.d.ts.map +1 -0
  51. package/dist/core/{token/gen-token-app/gen-token-server.js → auth/token-generator/server.js} +3 -3
  52. package/dist/core/auth/token-generator/server.js.map +1 -0
  53. package/dist/core/auth/types.d.ts +35 -0
  54. package/dist/core/auth/types.d.ts.map +1 -0
  55. package/dist/core/auth/types.js +14 -0
  56. package/dist/core/auth/types.js.map +1 -0
  57. package/dist/core/cache/cache.d.ts.map +1 -1
  58. package/dist/core/cache/cache.js +3 -2
  59. package/dist/core/cache/cache.js.map +1 -1
  60. package/dist/core/index.d.ts +5 -3
  61. package/dist/core/index.d.ts.map +1 -1
  62. package/dist/core/index.js +4 -2
  63. package/dist/core/index.js.map +1 -1
  64. package/dist/core/web/server-http.js +1 -1
  65. package/dist/core/web/server-http.js.map +1 -1
  66. package/package.json +2 -2
  67. package/dist/core/token/gen-token-app/gen-token-server.d.ts.map +0 -1
  68. package/dist/core/token/gen-token-app/gen-token-server.js.map +0 -1
  69. package/dist/core/token/gen-token-app/html.d.ts.map +0 -1
  70. package/dist/core/token/gen-token-app/html.js.map +0 -1
  71. package/dist/core/token/gen-token-app/ntlm-auth-options.d.ts.map +0 -1
  72. package/dist/core/token/gen-token-app/ntlm-auth-options.js.map +0 -1
  73. package/dist/core/token/gen-token-app/ntlm-domain-config.d.ts.map +0 -1
  74. package/dist/core/token/gen-token-app/ntlm-domain-config.js.map +0 -1
  75. package/dist/core/token/gen-token-app/ntlm-integration.d.ts.map +0 -1
  76. package/dist/core/token/gen-token-app/ntlm-integration.js.map +0 -1
  77. package/dist/core/token/gen-token-app/ntlm-session-storage.d.ts.map +0 -1
  78. package/dist/core/token/gen-token-app/ntlm-session-storage.js.map +0 -1
  79. package/dist/core/token/gen-token-app/ntlm-templates.d.ts.map +0 -1
  80. package/dist/core/token/gen-token-app/ntlm-templates.js.map +0 -1
  81. package/dist/core/token/i-token.d.ts +0 -13
  82. package/dist/core/token/i-token.d.ts.map +0 -1
  83. package/dist/core/token/i-token.js +0 -2
  84. package/dist/core/token/i-token.js.map +0 -1
  85. package/dist/core/token/token-auth.d.ts +0 -17
  86. package/dist/core/token/token-auth.d.ts.map +0 -1
  87. package/dist/core/token/token-auth.js.map +0 -1
  88. package/dist/core/token/token-core.d.ts.map +0 -1
  89. package/dist/core/token/token-core.js.map +0 -1
  90. /package/dist/core/{token/gen-token-app → auth/token-generator}/html.d.ts +0 -0
  91. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-auth-options.d.ts +0 -0
  92. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-domain-config.d.ts +0 -0
  93. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-domain-config.js +0 -0
  94. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-integration.d.ts +0 -0
  95. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-session-storage.d.ts +0 -0
  96. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-templates.d.ts +0 -0
  97. /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-templates.js +0 -0
@@ -0,0 +1,252 @@
1
+ // noinspection UnnecessaryLocalVariableJS
2
+
3
+ /**
4
+ * Example: Custom Basic Authentication Implementation
5
+ *
6
+ * This example shows how to implement custom basic authentication
7
+ * validation with fa-mcp-sdk multi-authentication system.
8
+ */
9
+
10
+ // @ts-ignore
11
+ import { McpServerData, CustomBasicAuthValidator, initMcpServer } from 'fa-mcp-sdk';
12
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
13
+
14
+ // ========================================================================
15
+ // EXAMPLE 1: Database-backed Authentication
16
+ // ========================================================================
17
+
18
+ /**
19
+ * Custom validator using database lookup
20
+ */
21
+ const databaseBasicAuthValidator: CustomBasicAuthValidator = async (username: string, password: string): Promise<boolean> => {
22
+ // Example: Check credentials against a database
23
+ try {
24
+ // This would be your actual database query
25
+ const user = await getUserFromDatabase(username);
26
+
27
+ if (!user) {
28
+ return false;
29
+ }
30
+
31
+ // Example: Compare hashed password
32
+ const isValidPassword = await comparePassword(password, user.hashedPassword);
33
+ return isValidPassword;
34
+
35
+ } catch (error) {
36
+ console.error('Database authentication error:', error);
37
+ return false;
38
+ }
39
+ };
40
+
41
+ // ========================================================================
42
+ // EXAMPLE 2: LDAP/Active Directory Authentication
43
+ // ========================================================================
44
+
45
+ /**
46
+ * Custom validator using LDAP/AD
47
+ */
48
+ const ldapBasicAuthValidator: CustomBasicAuthValidator = async (username: string, password: string): Promise<boolean> => {
49
+ try {
50
+ // Example LDAP authentication
51
+ const ldapResult = await authenticateWithLDAP(username, password);
52
+ return ldapResult.success;
53
+
54
+ } catch (error) {
55
+ console.error('LDAP authentication error:', error);
56
+ return false;
57
+ }
58
+ };
59
+
60
+ // ========================================================================
61
+ // EXAMPLE 3: External API Authentication
62
+ // ========================================================================
63
+
64
+ /**
65
+ * Custom validator using external authentication service
66
+ */
67
+ const externalApiAuthValidator: CustomBasicAuthValidator = async (username: string, password: string): Promise<boolean> => {
68
+ try {
69
+ const response = await fetch('https://auth.example.com/validate', {
70
+ method: 'POST',
71
+ headers: { 'Content-Type': 'application/json' },
72
+ body: JSON.stringify({ username, password }),
73
+ });
74
+
75
+ if (!response.ok) {
76
+ return false;
77
+ }
78
+
79
+ const result: any = await response.json();
80
+ return result.valid === true;
81
+
82
+ } catch (error) {
83
+ console.error('External API authentication error:', error);
84
+ return false;
85
+ }
86
+ };
87
+
88
+ // ========================================================================
89
+ // EXAMPLE 4: Multi-factor Authentication
90
+ // ========================================================================
91
+
92
+ /**
93
+ * Custom validator with multi-factor authentication
94
+ */
95
+ const mfaBasicAuthValidator: CustomBasicAuthValidator = async (username: string, password: string): Promise<boolean> => {
96
+ try {
97
+ // Password format: "actualPassword:mfaToken"
98
+ const [actualPassword, mfaToken] = password.split(':');
99
+
100
+ if (!actualPassword || !mfaToken) {
101
+ return false;
102
+ }
103
+
104
+ // Validate base credentials
105
+ const user = await getUserFromDatabase(username);
106
+ if (!user || !(await comparePassword(actualPassword, user.hashedPassword))) {
107
+ return false;
108
+ }
109
+
110
+ // Validate MFA token
111
+ const mfaValid = await validateMFAToken(username, mfaToken);
112
+ return mfaValid;
113
+
114
+ } catch (error) {
115
+ console.error('MFA authentication error:', error);
116
+ return false;
117
+ }
118
+ };
119
+
120
+ // ========================================================================
121
+ // MCP SERVER INITIALIZATION WITH CUSTOM AUTH
122
+ // ========================================================================
123
+
124
+ const tools: Tool[] = [
125
+ {
126
+ name: 'example-tool',
127
+ description: 'An example tool',
128
+ inputSchema: {
129
+ type: 'object',
130
+ properties: {
131
+ message: { type: 'string' },
132
+ },
133
+ },
134
+ },
135
+ ];
136
+
137
+ const toolHandler = async (params: { name: string; arguments?: any }) => {
138
+ return { content: [{ type: 'text', text: `Tool ${params.name} executed` }] };
139
+ };
140
+
141
+ const mcpServerData: McpServerData = {
142
+ tools,
143
+ toolHandler,
144
+ agentBrief: 'Example MCP Server with Custom Basic Auth',
145
+ agentPrompt: 'This server demonstrates custom basic authentication.',
146
+
147
+ // Custom basic auth validator
148
+ // @ts-ignore
149
+ customBasicAuthValidator: databaseBasicAuthValidator, // or any of the other validators
150
+ };
151
+
152
+ // ========================================================================
153
+ // MOCK FUNCTIONS (Replace with your actual implementations)
154
+ // ========================================================================
155
+
156
+ async function getUserFromDatabase (username: string): Promise<{ hashedPassword: string } | null> {
157
+ // Mock implementation - replace with your database query
158
+ const mockUsers = {
159
+ 'admin': { hashedPassword: 'hashed_admin_password' },
160
+ 'user': { hashedPassword: 'hashed_user_password' },
161
+ };
162
+ return mockUsers[username as keyof typeof mockUsers] || null;
163
+ }
164
+
165
+ async function comparePassword (plaintext: string, hashed: string): Promise<boolean> {
166
+ // Mock implementation - replace with proper password hashing library (e.g., bcrypt)
167
+ return `hashed_${plaintext}_password` === hashed;
168
+ }
169
+
170
+ async function authenticateWithLDAP (username: string, password: string): Promise<{ success: boolean }> {
171
+ // Mock implementation - replace with actual LDAP client
172
+ return { success: username === 'ldapuser' && password === 'ldappassword' };
173
+ }
174
+
175
+ async function validateMFAToken (username: string, token: string): Promise<boolean> {
176
+ // Mock implementation - replace with actual MFA validation
177
+ return token === '123456'; // Mock 6-digit MFA token
178
+ }
179
+
180
+ // ========================================================================
181
+ // START THE SERVER
182
+ // ========================================================================
183
+
184
+ // Initialize and start the MCP server with custom basic authentication
185
+ initMcpServer(mcpServerData).catch(console.error);
186
+
187
+ // ========================================================================
188
+ // CONFIGURATION EXAMPLE (config/default.yaml)
189
+ // ========================================================================
190
+
191
+ /*
192
+ webServer:
193
+ auth:
194
+ enabled: true
195
+ basic:
196
+ type: 'basic'
197
+ # When using custom validator, username/password can be anything or even omitted
198
+ # The custom validator function will handle the actual authentication
199
+ username: 'placeholder'
200
+ password: 'placeholder'
201
+ # Other auth types can be configured alongside custom basic auth
202
+ jwtToken:
203
+ encryptKey: 'your-secret-key'
204
+ checkMCPName: true
205
+ permanentServerTokens:
206
+ - 'server-token-1'
207
+ - 'server-token-2'
208
+ */
209
+
210
+ // ========================================================================
211
+ // USAGE EXAMPLES
212
+ // ========================================================================
213
+
214
+ /*
215
+ 1. Using curl with custom basic auth:
216
+
217
+ curl -X POST http://localhost:3000/mcp \
218
+ -H "Content-Type: application/json" \
219
+ -H "Authorization: Basic $(echo -n 'admin:adminpassword' | base64)" \
220
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
221
+
222
+ 2. With MFA (if using mfaBasicAuthValidator):
223
+
224
+ curl -X POST http://localhost:3000/mcp \
225
+ -H "Content-Type: application/json" \
226
+ -H "Authorization: Basic $(echo -n 'admin:adminpassword:123456' | base64)" \
227
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
228
+
229
+ 3. JavaScript client example:
230
+
231
+ const credentials = btoa('admin:adminpassword');
232
+ const response = await fetch('http://localhost:3000/mcp', {
233
+ method: 'POST',
234
+ headers: {
235
+ 'Content-Type': 'application/json',
236
+ 'Authorization': `Basic ${credentials}`
237
+ },
238
+ body: JSON.stringify({
239
+ jsonrpc: '2.0',
240
+ id: 1,
241
+ method: 'tools/list',
242
+ params: {}
243
+ })
244
+ });
245
+ */
246
+
247
+ export {
248
+ databaseBasicAuthValidator,
249
+ ldapBasicAuthValidator,
250
+ externalApiAuthValidator,
251
+ mfaBasicAuthValidator,
252
+ };
@@ -0,0 +1,333 @@
1
+ /**
2
+ * Примеры использования системы мультиаутентификации fa-mcp-sdk
3
+ */
4
+
5
+ import express from 'express';
6
+ // @ts-ignore
7
+ import { appConfig, enhancedAuthTokenMW, createConfigurableAuthMiddleware, getMultiAuthError, getAuthInfo, checkMultiAuth, detectAuthConfiguration, logAuthConfiguration } from 'fa-mcp-sdk';
8
+
9
+ // ========================================================================
10
+ // ПРИМЕР 1: ПРОСТАЯ ЗАМЕНА MIDDLEWARE
11
+ // ========================================================================
12
+
13
+ const app = express();
14
+
15
+ // Вместо старого authTokenMW используем enhancedAuthTokenMW
16
+ app.use('/api', enhancedAuthTokenMW);
17
+
18
+ app.get('/api/protected', (req, res) => {
19
+ const authInfo = (req as any).authInfo;
20
+ res.json({
21
+ message: 'Access granted',
22
+ authType: authInfo?.authType,
23
+ username: authInfo?.username,
24
+ tokenType: authInfo?.tokenType,
25
+ });
26
+ });
27
+
28
+ // ========================================================================
29
+ // ПРИМЕР 2: КОНФИГУРИРУЕМЫЙ MIDDLEWARE
30
+ // ========================================================================
31
+
32
+ // Middleware с логированием конфигурации при запуске
33
+ const authWithLogging = createConfigurableAuthMiddleware({
34
+ logConfiguration: true,
35
+ forceMultiAuth: false, // Автоматически определяет нужна ли мультиаут
36
+ });
37
+
38
+ app.use('/api/v2', authWithLogging);
39
+
40
+ // ========================================================================
41
+ // ПРИМЕР 3: КАСТОМНАЯ ЛОГИКА АУТЕНТИФИКАЦИИ
42
+ // ========================================================================
43
+
44
+ app.use('/api/custom', async (req, res, next) => {
45
+ // Публичные эндпоинты
46
+ if (req.path.startsWith('/api/custom/public')) {
47
+ return next();
48
+ }
49
+
50
+ // Для админских эндпоинтов требуем только permanent tokens
51
+ if (req.path.startsWith('/api/custom/admin')) {
52
+ const token = (req.headers.authorization || '').replace(/^Bearer */, '');
53
+ const auth = appConfig.webServer.auth;
54
+
55
+ if (auth.permanentServerTokens.includes(token)) {
56
+ return next();
57
+ } else {
58
+ return res.status(403).json({ error: 'Admin access required' });
59
+ }
60
+ }
61
+
62
+ try {
63
+ // Для остальных используем полную мультиаутентификацию
64
+ const authError = await getMultiAuthError(req);
65
+ if (authError) {
66
+ res.status(authError.code).send(authError.message);
67
+ return;
68
+ }
69
+ next();
70
+ } catch (error) {
71
+ res.status(500).send('Authentication error');
72
+ return;
73
+ }
74
+ });
75
+
76
+ // ========================================================================
77
+ // ПРИМЕР 4: РОУТЕР С РАЗНЫМИ УРОВНЯМИ ДОСТУПА
78
+ // ========================================================================
79
+
80
+ const apiRouter = express.Router();
81
+
82
+ // Публичные роуты - без аутентификации
83
+ apiRouter.get('/health', (req, res) => {
84
+ res.json({ status: 'ok' });
85
+ });
86
+
87
+ apiRouter.get('/info', (req, res) => {
88
+ const authInfo = getAuthInfo();
89
+ res.json({
90
+ authEnabled: authInfo.enabled,
91
+ configuredTypes: authInfo.configured,
92
+ validTypes: authInfo.valid,
93
+ usingMultiAuth: authInfo.usingMultiAuth,
94
+ });
95
+ });
96
+
97
+ // Защищенные роуты - с мультиаутентификацией
98
+ apiRouter.use('/protected', enhancedAuthTokenMW);
99
+
100
+ apiRouter.get('/protected/profile', (req, res) => {
101
+ const authInfo = (req as any).authInfo;
102
+ res.json({
103
+ profile: {
104
+ authType: authInfo.authType,
105
+ username: authInfo.username || 'anonymous',
106
+ permissions: getPermissionsForAuthType(authInfo.authType),
107
+ },
108
+ });
109
+ });
110
+
111
+ apiRouter.get('/protected/data', (req, res) => {
112
+ const authInfo = (req as any).authInfo;
113
+
114
+ // Разные данные в зависимости от типа аутентификации
115
+ let data;
116
+ switch (authInfo.authType) {
117
+ case 'permanentServerTokens':
118
+ data = { level: 'server', access: 'full' };
119
+ break;
120
+ case 'oauth2':
121
+ data = { level: 'user', access: 'scoped', scopes: authInfo.payload?.scope };
122
+ break;
123
+ case 'basic':
124
+ data = { level: 'basic', access: 'limited', username: authInfo.username };
125
+ break;
126
+ case 'pat':
127
+ data = { level: 'api', access: 'token-based' };
128
+ break;
129
+ case 'jwtToken':
130
+ data = { level: 'jwt', access: 'custom', payload: authInfo.payload };
131
+ break;
132
+ default:
133
+ data = { level: 'unknown', access: 'none' };
134
+ }
135
+
136
+ res.json({ data, authInfo: authInfo.authType });
137
+ });
138
+
139
+ app.use('/api/v3', apiRouter);
140
+
141
+ // ========================================================================
142
+ // ПРИМЕР 5: ПРОГРАММНОЕ ТЕСТИРОВАНИЕ ТОКЕНОВ
143
+ // ========================================================================
144
+
145
+ app.post('/api/test-token', async (req, res) => {
146
+ const { token } = req.body;
147
+
148
+ if (!token) {
149
+ return res.status(400).json({ error: 'Token required' });
150
+ }
151
+
152
+ try {
153
+ const authConfig = appConfig.webServer.auth;
154
+ const result = await checkMultiAuth(token, authConfig);
155
+
156
+ return res.json({
157
+ valid: result.success,
158
+ authType: result.authType,
159
+ tokenType: result.tokenType,
160
+ error: result.error,
161
+ username: result.username,
162
+ hasPayload: !!result.payload,
163
+ });
164
+ } catch (error) {
165
+ return res.status(500).json({ error: 'Authentication test failed' });
166
+ }
167
+ });
168
+
169
+ // ========================================================================
170
+ // ПРИМЕР 6: MIDDLEWARE ДЛЯ РАЗНЫХ ТИПОВ API
171
+ // ========================================================================
172
+
173
+ // REST API - требует любую валидную аутентификацию
174
+ app.use('/rest', enhancedAuthTokenMW);
175
+
176
+ // GraphQL API - требует user-level аутентификацию (не server tokens)
177
+ app.use('/graphql', async (req, res, next) => {
178
+ try {
179
+ const authError = await getMultiAuthError(req);
180
+ if (authError) {
181
+ return res.status(authError.code).send(authError.message);
182
+ }
183
+
184
+ const authInfo = (req as any).authInfo;
185
+ if (authInfo.authType === 'permanentServerTokens') {
186
+ return res.status(403).json({
187
+ error: 'GraphQL API requires user authentication, server tokens not allowed',
188
+ });
189
+ }
190
+
191
+ return next();
192
+ } catch (error) {
193
+ return res.status(500).send('Authentication error');
194
+ }
195
+ });
196
+
197
+ // WebSocket API - только JWT токены (для real-time connections)
198
+ app.use('/ws', async (req, res, next) => {
199
+ try {
200
+ const authError = await getMultiAuthError(req);
201
+ if (authError) {
202
+ return res.status(authError.code).send(authError.message);
203
+ }
204
+
205
+ const authInfo = (req as any).authInfo;
206
+ if (authInfo.authType !== 'jwtToken' && authInfo.authType !== 'oauth2') {
207
+ return res.status(403).json({
208
+ error: 'WebSocket API requires JWT or OAuth2 tokens for session management',
209
+ });
210
+ }
211
+
212
+ return next();
213
+ } catch {
214
+ return res.status(500).send('Authentication error');
215
+ }
216
+ });
217
+
218
+ // ========================================================================
219
+ // УТИЛИТНЫЕ ФУНКЦИИ
220
+ // ========================================================================
221
+
222
+ export function getPermissionsForAuthType (authType: string): string[] {
223
+ const permissions: Record<string, string[]> = {
224
+ 'permanentServerTokens': ['read', 'write', 'admin', 'server'],
225
+ 'oauth2': ['read', 'write', 'user'],
226
+ 'jwtToken': ['read', 'write', 'session'],
227
+ 'pat': ['read', 'write', 'api'],
228
+ 'basic': ['read', 'basic'],
229
+ };
230
+
231
+ return permissions[authType] || ['read'];
232
+ }
233
+
234
+ // ========================================================================
235
+ // ПРИМЕР 7: ИНИЦИАЛИЗАЦИЯ С ДИАГНОСТИКОЙ
236
+ // ========================================================================
237
+
238
+ export function initializeAuthSystem () {
239
+ const authConfig = appConfig.webServer.auth;
240
+
241
+ console.log('🔐 Initializing Multi-Authentication System...');
242
+
243
+ // Диагностика конфигурации
244
+ const detection = detectAuthConfiguration(authConfig);
245
+
246
+ console.log('📊 Auth Configuration:');
247
+ console.log(` Enabled: ${authConfig.enabled}`);
248
+ console.log(` Configured: ${detection.configured.join(', ')}`);
249
+ console.log(` Valid: ${detection.valid.join(', ')}`);
250
+
251
+ if (Object.keys(detection.errors).length > 0) {
252
+ console.warn('⚠️ Configuration Issues:');
253
+ Object.entries(detection.errors).forEach(([type, errors]) => {
254
+ console.warn(` ${type}: ${(errors as string[]).join(', ')}`);
255
+ });
256
+ }
257
+
258
+ // Логирование для отладки
259
+ logAuthConfiguration(authConfig);
260
+
261
+ console.log('✅ Multi-Authentication System initialized successfully');
262
+
263
+ return {
264
+ configured: detection.configured,
265
+ valid: detection.valid,
266
+ errors: detection.errors,
267
+ usingMultiAuth: !!(authConfig.pat || authConfig.basic || authConfig.oauth2),
268
+ };
269
+ }
270
+
271
+ // ========================================================================
272
+ // ПРИМЕР 8: ТЕСТИРОВАНИЕ КОНФИГУРАЦИИ
273
+ // ========================================================================
274
+
275
+ export async function testAuthConfiguration () {
276
+ const authConfig = appConfig.webServer.auth;
277
+
278
+ console.log('🧪 Testing Authentication Configuration...');
279
+
280
+ const testCases = [
281
+ // Тест permanent token
282
+ {
283
+ name: 'Permanent Server Token',
284
+ token: authConfig.permanentServerTokens[0],
285
+ expectedType: 'permanentServerTokens',
286
+ },
287
+ // Тест PAT
288
+ {
289
+ name: 'Personal Access Token',
290
+ token: authConfig.pat,
291
+ expectedType: 'pat',
292
+ },
293
+ // Тест basic auth
294
+ {
295
+ name: 'Basic Authentication',
296
+ token: authConfig.basic
297
+ ? Buffer.from(`${authConfig.basic.username}:${authConfig.basic.password}`).toString('base64')
298
+ : undefined,
299
+ expectedType: 'basic',
300
+ },
301
+ // Тест OAuth2
302
+ {
303
+ name: 'OAuth2 Bearer Token',
304
+ token: authConfig.oauth2 ? `Bearer ${authConfig.oauth2.accessToken}` : undefined,
305
+ expectedType: 'oauth2',
306
+ },
307
+ ];
308
+
309
+ for (const testCase of testCases) {
310
+ if (!testCase.token) {
311
+ console.log(`⏭️ Skipping ${testCase.name}: not configured`);
312
+ continue;
313
+ }
314
+
315
+ try {
316
+ const result = await checkMultiAuth(testCase.token, authConfig);
317
+
318
+ if (result.success && result.authType === testCase.expectedType) {
319
+ console.log(`✅ ${testCase.name}: PASSED`);
320
+ } else {
321
+ console.log(`❌ ${testCase.name}: FAILED - ${result.error || 'Unexpected auth type'}`);
322
+ }
323
+ } catch (error) {
324
+ console.log(`❌ ${testCase.name}: FAILED - Authentication test error`);
325
+ }
326
+ }
327
+
328
+ console.log('🧪 Authentication testing completed');
329
+ }
330
+
331
+ // ========================================================================
332
+ // ЭКСПОРТ ДЛЯ ИСПОЛЬЗОВАНИЯ
333
+ // ========================================================================
@@ -1,3 +1,4 @@
1
+ // @ts-ignore
1
2
  import { IResourceData } from 'fa-mcp-sdk';
2
3
 
3
4
  export const customResources: IResourceData[] = [