@mcp-abap-adt/header-validator 0.1.1 → 0.1.3
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/CHANGELOG.md +46 -0
- package/dist/headerValidator.js +52 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,52 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.3] - 2025-12-01
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **x-mcp-destination validation** – fixed issue where `x-mcp-destination` header incorrectly required `x-sap-url`:
|
|
12
|
+
- `x-mcp-destination` now works identically to `x-sap-destination` - URL is automatically derived from service key
|
|
13
|
+
- `x-sap-url` is now optional for `x-mcp-destination` (and will be ignored with a warning if provided)
|
|
14
|
+
- Fixed validation logic to check `x-mcp-destination` immediately after `x-sap-destination`, regardless of `x-sap-url` presence
|
|
15
|
+
- This fixes issues on Windows where `x-mcp-destination` was being ignored
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- **Header case handling** – improved header value extraction to check both lowercase and original case:
|
|
19
|
+
- `getHeaderValue()` now checks lowercase first (Node.js normalizes headers), then original case for compatibility
|
|
20
|
+
- Both `validateSapDestinationAuth()` and `validateMcpDestinationAuth()` check headers in both cases
|
|
21
|
+
- Better cross-platform compatibility, especially for Windows
|
|
22
|
+
|
|
23
|
+
- **Validation order** – improved validation priority logic:
|
|
24
|
+
- `x-mcp-destination` is now checked immediately after `x-sap-destination`, before checking for `x-sap-url`
|
|
25
|
+
- This ensures destination-based authentication is prioritized correctly
|
|
26
|
+
- URL validation only happens for non-destination authentication methods
|
|
27
|
+
|
|
28
|
+
- **Documentation updates** – updated architecture documentation:
|
|
29
|
+
- Updated `ARCHITECTURE.md` to reflect that `x-sap-url` is not required for `x-mcp-destination`
|
|
30
|
+
- Updated `PRIORITY_DIAGRAM.md` with correct header requirements
|
|
31
|
+
- Updated examples to show `x-mcp-destination` without `x-sap-url`
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Test coverage** – added tests for new validation behavior:
|
|
35
|
+
- Test for `x-mcp-destination` without `x-sap-url` (should work)
|
|
36
|
+
- Test for warning when `x-sap-url` is provided with `x-mcp-destination`
|
|
37
|
+
- Updated existing tests to reflect new validation logic
|
|
38
|
+
|
|
39
|
+
## [0.1.2] - 2025-11-30
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- **Improved header validation logic** - Absence of headers is no longer treated as an error (allows .env file usage)
|
|
43
|
+
- **MCP destination validation** - `validateMcpDestinationAuth` now accepts optional `sapUrl` parameter and validates it internally
|
|
44
|
+
- **Better error handling** - Validator returns empty errors array when no headers provided (not an error, user may use .env file)
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- **Test updates** - Updated tests to reflect new validation logic where missing headers are not errors
|
|
48
|
+
|
|
49
|
+
## [0.1.1] - 2025-11-30
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
- Initial published version
|
|
53
|
+
|
|
8
54
|
## [0.1.0] - 2025-11-30
|
|
9
55
|
|
|
10
56
|
### Added
|
package/dist/headerValidator.js
CHANGED
|
@@ -12,9 +12,15 @@ exports.validateAuthHeaders = validateAuthHeaders;
|
|
|
12
12
|
const types_1 = require("./types");
|
|
13
13
|
/**
|
|
14
14
|
* Extract header value (handles array values)
|
|
15
|
+
* Node.js normalizes headers to lowercase, but check both cases for safety
|
|
15
16
|
*/
|
|
16
17
|
function getHeaderValue(headers, name) {
|
|
17
|
-
|
|
18
|
+
// Try lowercase first (Node.js normalizes to lowercase)
|
|
19
|
+
let value = headers[name.toLowerCase()];
|
|
20
|
+
// If not found, try original case (for compatibility)
|
|
21
|
+
if (!value) {
|
|
22
|
+
value = headers[name];
|
|
23
|
+
}
|
|
18
24
|
if (!value) {
|
|
19
25
|
return undefined;
|
|
20
26
|
}
|
|
@@ -41,7 +47,8 @@ function isValidUrl(url) {
|
|
|
41
47
|
* URL is taken from destination (service key or .env), not from x-sap-url header
|
|
42
48
|
*/
|
|
43
49
|
function validateSapDestinationAuth(headers) {
|
|
44
|
-
|
|
50
|
+
// Check both lowercase and original case (Node.js normalizes to lowercase, but check both for safety)
|
|
51
|
+
const destinationRaw = headers['x-sap-destination'] || headers['X-SAP-Destination'];
|
|
45
52
|
if (!destinationRaw) {
|
|
46
53
|
return null;
|
|
47
54
|
}
|
|
@@ -94,9 +101,12 @@ function validateSapDestinationAuth(headers) {
|
|
|
94
101
|
/**
|
|
95
102
|
* Validate MCP destination-based authentication (medium-high priority)
|
|
96
103
|
* x-mcp-destination - uses AuthBroker, always JWT (no x-sap-auth-type needed)
|
|
104
|
+
* URL is taken from destination (service key or .env), not from x-sap-url header
|
|
105
|
+
* x-sap-url is optional - if provided, it will be ignored (warning issued)
|
|
97
106
|
*/
|
|
98
107
|
function validateMcpDestinationAuth(headers, sapUrl) {
|
|
99
|
-
|
|
108
|
+
// Check both lowercase and original case (Node.js normalizes to lowercase, but check both for safety)
|
|
109
|
+
const destinationRaw = headers['x-mcp-destination'] || headers['X-MCP-Destination'];
|
|
100
110
|
if (!destinationRaw) {
|
|
101
111
|
return null;
|
|
102
112
|
}
|
|
@@ -109,11 +119,15 @@ function validateMcpDestinationAuth(headers, sapUrl) {
|
|
|
109
119
|
return {
|
|
110
120
|
priority: types_1.AuthMethodPriority.NONE,
|
|
111
121
|
authType: 'jwt', // MCP destination always uses JWT
|
|
112
|
-
sapUrl,
|
|
122
|
+
sapUrl: '', // URL will be loaded from destination
|
|
113
123
|
errors,
|
|
114
124
|
warnings,
|
|
115
125
|
};
|
|
116
126
|
}
|
|
127
|
+
// Warning if x-sap-url is provided (URL comes from destination, not header)
|
|
128
|
+
if (sapUrl) {
|
|
129
|
+
warnings.push('x-sap-url is ignored when x-mcp-destination is present (URL is loaded from destination service key or .env file)');
|
|
130
|
+
}
|
|
117
131
|
// Warning if x-sap-auth-type is provided (not needed for x-mcp-destination)
|
|
118
132
|
const authType = getHeaderValue(headers, 'x-sap-auth-type');
|
|
119
133
|
if (authType) {
|
|
@@ -129,7 +143,7 @@ function validateMcpDestinationAuth(headers, sapUrl) {
|
|
|
129
143
|
return {
|
|
130
144
|
priority: types_1.AuthMethodPriority.MCP_DESTINATION,
|
|
131
145
|
authType: 'jwt', // Always JWT for x-mcp-destination
|
|
132
|
-
sapUrl,
|
|
146
|
+
sapUrl: '', // URL will be loaded from destination (service key or .env)
|
|
133
147
|
sapClient,
|
|
134
148
|
destination,
|
|
135
149
|
errors,
|
|
@@ -224,11 +238,11 @@ function validateBasicAuth(headers, sapUrl, authType) {
|
|
|
224
238
|
* @returns Validation result with prioritized authentication configuration
|
|
225
239
|
*/
|
|
226
240
|
function validateAuthHeaders(headers) {
|
|
227
|
-
// No headers provided
|
|
241
|
+
// No headers provided - this is not an error, user may be using .env file
|
|
228
242
|
if (!headers) {
|
|
229
243
|
return {
|
|
230
244
|
isValid: false,
|
|
231
|
-
errors: [
|
|
245
|
+
errors: [],
|
|
232
246
|
warnings: [],
|
|
233
247
|
};
|
|
234
248
|
}
|
|
@@ -255,15 +269,35 @@ function validateAuthHeaders(headers) {
|
|
|
255
269
|
};
|
|
256
270
|
}
|
|
257
271
|
}
|
|
258
|
-
//
|
|
272
|
+
// Check for MCP destination (doesn't require x-sap-url, URL comes from destination)
|
|
259
273
|
const sapUrl = getHeaderValue(headers, 'x-sap-url');
|
|
260
|
-
|
|
274
|
+
const mcpDestinationConfig = validateMcpDestinationAuth(headers, sapUrl);
|
|
275
|
+
if (mcpDestinationConfig) {
|
|
276
|
+
// MCP destination found - URL comes from destination, not header
|
|
277
|
+
if (mcpDestinationConfig.errors.length === 0) {
|
|
278
|
+
return {
|
|
279
|
+
isValid: true,
|
|
280
|
+
config: mcpDestinationConfig,
|
|
281
|
+
errors: [],
|
|
282
|
+
warnings: mcpDestinationConfig.warnings,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
// Has errors, continue to check other methods or return error
|
|
287
|
+
return {
|
|
288
|
+
isValid: false,
|
|
289
|
+
errors: mcpDestinationConfig.errors,
|
|
290
|
+
warnings: mcpDestinationConfig.warnings,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// For other auth methods, x-sap-url is required
|
|
261
295
|
if (!sapUrl) {
|
|
262
|
-
|
|
296
|
+
// If no auth headers at all, return empty result (not an error - may use .env file)
|
|
263
297
|
return {
|
|
264
298
|
isValid: false,
|
|
265
|
-
errors,
|
|
266
|
-
warnings,
|
|
299
|
+
errors: [],
|
|
300
|
+
warnings: [],
|
|
267
301
|
};
|
|
268
302
|
}
|
|
269
303
|
// Validate URL format
|
|
@@ -277,11 +311,6 @@ function validateAuthHeaders(headers) {
|
|
|
277
311
|
}
|
|
278
312
|
// Try to validate authentication methods in priority order
|
|
279
313
|
const configs = [];
|
|
280
|
-
// 2. MCP destination-based auth (medium-high priority) - doesn't require x-sap-auth-type
|
|
281
|
-
const mcpDestinationConfig = validateMcpDestinationAuth(headers, sapUrl);
|
|
282
|
-
if (mcpDestinationConfig) {
|
|
283
|
-
configs.push(mcpDestinationConfig);
|
|
284
|
-
}
|
|
285
314
|
// 3. Other auth methods require x-sap-auth-type
|
|
286
315
|
const sapAuthType = getHeaderValue(headers, 'x-sap-auth-type');
|
|
287
316
|
if (sapAuthType) {
|
|
@@ -325,9 +354,12 @@ function validateAuthHeaders(headers) {
|
|
|
325
354
|
errors.push('Basic authentication requires x-sap-login and x-sap-password headers');
|
|
326
355
|
}
|
|
327
356
|
}
|
|
328
|
-
else
|
|
329
|
-
// MCP destination was found but has errors
|
|
330
|
-
|
|
357
|
+
else {
|
|
358
|
+
// Check if MCP destination was found but has errors
|
|
359
|
+
const mcpConfig = validateMcpDestinationAuth(headers, sapUrl);
|
|
360
|
+
if (mcpConfig && mcpConfig.errors.length > 0) {
|
|
361
|
+
errors.push(...mcpConfig.errors);
|
|
362
|
+
}
|
|
331
363
|
}
|
|
332
364
|
return {
|
|
333
365
|
isValid: false,
|
package/package.json
CHANGED