@mcp-abap-adt/auth-broker 0.1.4 → 0.1.6
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 +287 -0
- package/README.md +186 -9
- package/bin/generate-env-from-service-key.ts +128 -0
- package/dist/AuthBroker.d.ts +19 -35
- package/dist/AuthBroker.d.ts.map +1 -1
- package/dist/AuthBroker.js +87 -149
- package/dist/__tests__/helpers/configHelpers.d.ts +49 -0
- package/dist/__tests__/helpers/configHelpers.d.ts.map +1 -0
- package/dist/__tests__/helpers/configHelpers.js +169 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -7
- package/dist/providers/ITokenProvider.d.ts +49 -0
- package/dist/providers/ITokenProvider.d.ts.map +1 -0
- package/dist/providers/ITokenProvider.js +10 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +8 -0
- package/dist/stores/index.d.ts +5 -4
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/index.js +4 -6
- package/dist/stores/interfaces.d.ts +90 -20
- package/dist/stores/interfaces.d.ts.map +1 -1
- package/dist/stores/interfaces.js +1 -2
- package/dist/types.d.ts +7 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/package.json +13 -6
- package/dist/__tests__/testHelpers.d.ts +0 -44
- package/dist/__tests__/testHelpers.d.ts.map +0 -1
- package/dist/__tests__/testHelpers.js +0 -129
- package/dist/browserAuth.d.ts +0 -17
- package/dist/browserAuth.d.ts.map +0 -1
- package/dist/browserAuth.js +0 -305
- package/dist/cache.d.ts +0 -20
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -46
- package/dist/envLoader.d.ts +0 -12
- package/dist/envLoader.d.ts.map +0 -1
- package/dist/envLoader.js +0 -90
- package/dist/getToken.d.ts +0 -14
- package/dist/getToken.d.ts.map +0 -1
- package/dist/getToken.js +0 -62
- package/dist/logger.d.ts +0 -40
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -186
- package/dist/pathResolver.d.ts +0 -21
- package/dist/pathResolver.d.ts.map +0 -1
- package/dist/pathResolver.js +0 -105
- package/dist/refreshToken.d.ts +0 -14
- package/dist/refreshToken.d.ts.map +0 -1
- package/dist/refreshToken.js +0 -71
- package/dist/serviceKeyLoader.d.ts +0 -12
- package/dist/serviceKeyLoader.d.ts.map +0 -1
- package/dist/serviceKeyLoader.js +0 -72
- package/dist/stores/FileServiceKeyStore.d.ts +0 -38
- package/dist/stores/FileServiceKeyStore.d.ts.map +0 -1
- package/dist/stores/FileServiceKeyStore.js +0 -47
- package/dist/stores/FileSessionStore.d.ts +0 -50
- package/dist/stores/FileSessionStore.d.ts.map +0 -1
- package/dist/stores/FileSessionStore.js +0 -116
- package/dist/tokenRefresher.d.ts +0 -17
- package/dist/tokenRefresher.d.ts.map +0 -1
- package/dist/tokenRefresher.js +0 -53
- package/dist/tokenStorage.d.ts +0 -15
- package/dist/tokenStorage.d.ts.map +0 -1
- package/dist/tokenStorage.js +0 -107
- package/dist/tokenValidator.d.ts +0 -11
- package/dist/tokenValidator.d.ts.map +0 -1
- package/dist/tokenValidator.js +0 -108
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* File-based implementation of SessionStore
|
|
4
|
-
*
|
|
5
|
-
* Reads/writes session data from/to {destination}.env files in search paths.
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.FileSessionStore = void 0;
|
|
42
|
-
const envLoader_1 = require("../envLoader");
|
|
43
|
-
const tokenStorage_1 = require("../tokenStorage");
|
|
44
|
-
const pathResolver_1 = require("../pathResolver");
|
|
45
|
-
/**
|
|
46
|
-
* File-based session store implementation
|
|
47
|
-
*
|
|
48
|
-
* Searches for {destination}.env files in configured search paths.
|
|
49
|
-
* Writes to first search path (highest priority).
|
|
50
|
-
* Search paths priority:
|
|
51
|
-
* 1. Constructor parameter (highest)
|
|
52
|
-
* 2. AUTH_BROKER_PATH environment variable
|
|
53
|
-
* 3. Current working directory (lowest)
|
|
54
|
-
*/
|
|
55
|
-
class FileSessionStore {
|
|
56
|
-
searchPaths;
|
|
57
|
-
/**
|
|
58
|
-
* Create a new FileSessionStore instance
|
|
59
|
-
* @param searchPaths Optional search paths for .env files.
|
|
60
|
-
* Can be a single path (string) or array of paths.
|
|
61
|
-
* If not provided, uses AUTH_BROKER_PATH env var or current working directory.
|
|
62
|
-
*/
|
|
63
|
-
constructor(searchPaths) {
|
|
64
|
-
this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(searchPaths);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Load session configuration for destination
|
|
68
|
-
* @param destination Destination name (e.g., "TRIAL")
|
|
69
|
-
* @returns EnvConfig object or null if not found
|
|
70
|
-
*/
|
|
71
|
-
async loadSession(destination) {
|
|
72
|
-
return (0, envLoader_1.loadEnvFile)(destination, this.searchPaths);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Save session configuration for destination
|
|
76
|
-
* @param destination Destination name (e.g., "TRIAL")
|
|
77
|
-
* @param config Session configuration to save
|
|
78
|
-
*/
|
|
79
|
-
async saveSession(destination, config) {
|
|
80
|
-
// Save to first search path (highest priority)
|
|
81
|
-
const savePath = this.searchPaths[0];
|
|
82
|
-
// Convert EnvConfig to format expected by saveTokenToEnv
|
|
83
|
-
await (0, tokenStorage_1.saveTokenToEnv)(destination, savePath, {
|
|
84
|
-
sapUrl: config.sapUrl,
|
|
85
|
-
jwtToken: config.jwtToken,
|
|
86
|
-
refreshToken: config.refreshToken,
|
|
87
|
-
uaaUrl: config.uaaUrl,
|
|
88
|
-
uaaClientId: config.uaaClientId,
|
|
89
|
-
uaaClientSecret: config.uaaClientSecret,
|
|
90
|
-
sapClient: config.sapClient,
|
|
91
|
-
language: config.language,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Delete session for destination
|
|
96
|
-
* @param destination Destination name (e.g., "TRIAL")
|
|
97
|
-
*/
|
|
98
|
-
async deleteSession(destination) {
|
|
99
|
-
// Find .env file in search paths
|
|
100
|
-
const fileName = `${destination}.env`;
|
|
101
|
-
const { findFileInPaths } = await Promise.resolve().then(() => __importStar(require('../pathResolver')));
|
|
102
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
103
|
-
const envFilePath = findFileInPaths(fileName, this.searchPaths);
|
|
104
|
-
if (envFilePath && fs.existsSync(envFilePath)) {
|
|
105
|
-
fs.unlinkSync(envFilePath);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Get search paths (for error messages)
|
|
110
|
-
* @returns Array of search paths
|
|
111
|
-
*/
|
|
112
|
-
getSearchPaths() {
|
|
113
|
-
return [...this.searchPaths];
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
exports.FileSessionStore = FileSessionStore;
|
package/dist/tokenRefresher.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token refresher - refreshes JWT tokens using refresh token
|
|
3
|
-
*/
|
|
4
|
-
export interface TokenRefreshResult {
|
|
5
|
-
accessToken: string;
|
|
6
|
-
refreshToken?: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Refreshes the access token using refresh token
|
|
10
|
-
* @param refreshToken Refresh token
|
|
11
|
-
* @param uaaUrl UAA URL (e.g., https://your-account.authentication.eu10.hana.ondemand.com)
|
|
12
|
-
* @param clientId UAA client ID
|
|
13
|
-
* @param clientSecret UAA client secret
|
|
14
|
-
* @returns Promise that resolves to new tokens
|
|
15
|
-
*/
|
|
16
|
-
export declare function refreshJwtToken(refreshToken: string, uaaUrl: string, clientId: string, clientSecret: string): Promise<TokenRefreshResult>;
|
|
17
|
-
//# sourceMappingURL=tokenRefresher.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokenRefresher.d.ts","sourceRoot":"","sources":["../src/tokenRefresher.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAqC7B"}
|
package/dist/tokenRefresher.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Token refresher - refreshes JWT tokens using refresh token
|
|
4
|
-
*/
|
|
5
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.refreshJwtToken = refreshJwtToken;
|
|
10
|
-
const axios_1 = __importDefault(require("axios"));
|
|
11
|
-
/**
|
|
12
|
-
* Refreshes the access token using refresh token
|
|
13
|
-
* @param refreshToken Refresh token
|
|
14
|
-
* @param uaaUrl UAA URL (e.g., https://your-account.authentication.eu10.hana.ondemand.com)
|
|
15
|
-
* @param clientId UAA client ID
|
|
16
|
-
* @param clientSecret UAA client secret
|
|
17
|
-
* @returns Promise that resolves to new tokens
|
|
18
|
-
*/
|
|
19
|
-
async function refreshJwtToken(refreshToken, uaaUrl, clientId, clientSecret) {
|
|
20
|
-
try {
|
|
21
|
-
const tokenUrl = `${uaaUrl}/oauth/token`;
|
|
22
|
-
const params = new URLSearchParams();
|
|
23
|
-
params.append('grant_type', 'refresh_token');
|
|
24
|
-
params.append('refresh_token', refreshToken);
|
|
25
|
-
const authString = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
|
|
26
|
-
const response = await (0, axios_1.default)({
|
|
27
|
-
method: 'post',
|
|
28
|
-
url: tokenUrl,
|
|
29
|
-
headers: {
|
|
30
|
-
Authorization: `Basic ${authString}`,
|
|
31
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
32
|
-
},
|
|
33
|
-
data: params.toString(),
|
|
34
|
-
});
|
|
35
|
-
if (response.data && response.data.access_token) {
|
|
36
|
-
return {
|
|
37
|
-
accessToken: response.data.access_token,
|
|
38
|
-
refreshToken: response.data.refresh_token || refreshToken, // Use new refresh token if provided, otherwise keep old one
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
throw new Error('Response does not contain access_token');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
if (error.response) {
|
|
47
|
-
throw new Error(`Token refresh failed (${error.response.status}): ${JSON.stringify(error.response.data)}`);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
throw new Error(`Token refresh failed: ${error.message}`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
package/dist/tokenStorage.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token storage - saves tokens to .env files
|
|
3
|
-
*/
|
|
4
|
-
import { EnvConfig } from './types';
|
|
5
|
-
/**
|
|
6
|
-
* Save token to {destination}.env file
|
|
7
|
-
* @param destination Destination name
|
|
8
|
-
* @param savePath Path where to save the file
|
|
9
|
-
* @param config Configuration to save
|
|
10
|
-
*/
|
|
11
|
-
export declare function saveTokenToEnv(destination: string, savePath: string, config: Partial<EnvConfig> & {
|
|
12
|
-
sapUrl: string;
|
|
13
|
-
jwtToken: string;
|
|
14
|
-
}): Promise<void>;
|
|
15
|
-
//# sourceMappingURL=tokenStorage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokenStorage.d.ts","sourceRoot":"","sources":["../src/tokenStorage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,IAAI,CAAC,CA0Ef"}
|
package/dist/tokenStorage.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Token storage - saves tokens to .env files
|
|
4
|
-
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.saveTokenToEnv = saveTokenToEnv;
|
|
40
|
-
const fs = __importStar(require("fs"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
42
|
-
/**
|
|
43
|
-
* Save token to {destination}.env file
|
|
44
|
-
* @param destination Destination name
|
|
45
|
-
* @param savePath Path where to save the file
|
|
46
|
-
* @param config Configuration to save
|
|
47
|
-
*/
|
|
48
|
-
async function saveTokenToEnv(destination, savePath, config) {
|
|
49
|
-
// Ensure directory exists
|
|
50
|
-
if (!fs.existsSync(savePath)) {
|
|
51
|
-
fs.mkdirSync(savePath, { recursive: true });
|
|
52
|
-
}
|
|
53
|
-
const envFilePath = path.join(savePath, `${destination}.env`);
|
|
54
|
-
const tempFilePath = `${envFilePath}.tmp`;
|
|
55
|
-
// Read existing .env file if it exists
|
|
56
|
-
let existingContent = '';
|
|
57
|
-
if (fs.existsSync(envFilePath)) {
|
|
58
|
-
existingContent = fs.readFileSync(envFilePath, 'utf8');
|
|
59
|
-
}
|
|
60
|
-
// Parse existing content to preserve other values
|
|
61
|
-
const lines = existingContent.split('\n');
|
|
62
|
-
const existingVars = new Map();
|
|
63
|
-
for (const line of lines) {
|
|
64
|
-
const trimmed = line.trim();
|
|
65
|
-
if (!trimmed || trimmed.startsWith('#')) {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
const match = trimmed.match(/^([^=]+)=(.*)$/);
|
|
69
|
-
if (match) {
|
|
70
|
-
const key = match[1].trim();
|
|
71
|
-
const value = match[2].trim().replace(/^["']|["']$/g, ''); // Remove quotes
|
|
72
|
-
existingVars.set(key, value);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// Update with new values
|
|
76
|
-
existingVars.set('SAP_URL', config.sapUrl);
|
|
77
|
-
existingVars.set('SAP_JWT_TOKEN', config.jwtToken);
|
|
78
|
-
if (config.sapClient) {
|
|
79
|
-
existingVars.set('SAP_CLIENT', config.sapClient);
|
|
80
|
-
}
|
|
81
|
-
if (config.refreshToken) {
|
|
82
|
-
existingVars.set('SAP_REFRESH_TOKEN', config.refreshToken);
|
|
83
|
-
}
|
|
84
|
-
if (config.uaaUrl) {
|
|
85
|
-
existingVars.set('SAP_UAA_URL', config.uaaUrl);
|
|
86
|
-
}
|
|
87
|
-
if (config.uaaClientId) {
|
|
88
|
-
existingVars.set('SAP_UAA_CLIENT_ID', config.uaaClientId);
|
|
89
|
-
}
|
|
90
|
-
if (config.uaaClientSecret) {
|
|
91
|
-
existingVars.set('SAP_UAA_CLIENT_SECRET', config.uaaClientSecret);
|
|
92
|
-
}
|
|
93
|
-
// Write to temporary file first (atomic write)
|
|
94
|
-
const envLines = [];
|
|
95
|
-
for (const [key, value] of existingVars.entries()) {
|
|
96
|
-
// Escape value if it contains spaces or special characters
|
|
97
|
-
const escapedValue = value.includes(' ') || value.includes('=') || value.includes('#')
|
|
98
|
-
? `"${value.replace(/"/g, '\\"')}"`
|
|
99
|
-
: value;
|
|
100
|
-
envLines.push(`${key}=${escapedValue}`);
|
|
101
|
-
}
|
|
102
|
-
const envContent = envLines.join('\n') + '\n';
|
|
103
|
-
// Write to temp file
|
|
104
|
-
fs.writeFileSync(tempFilePath, envContent, 'utf8');
|
|
105
|
-
// Atomic rename
|
|
106
|
-
fs.renameSync(tempFilePath, envFilePath);
|
|
107
|
-
}
|
package/dist/tokenValidator.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token validator - validates JWT tokens by testing connection
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Validate JWT token by making a test request to SAP system
|
|
6
|
-
* @param token JWT token to validate
|
|
7
|
-
* @param sapUrl SAP system URL
|
|
8
|
-
* @returns true if token is valid, false if expired/invalid
|
|
9
|
-
*/
|
|
10
|
-
export declare function validateToken(token: string, sapUrl: string): Promise<boolean>;
|
|
11
|
-
//# sourceMappingURL=tokenValidator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokenValidator.d.ts","sourceRoot":"","sources":["../src/tokenValidator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA0EnF"}
|
package/dist/tokenValidator.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Token validator - validates JWT tokens by testing connection
|
|
4
|
-
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.validateToken = validateToken;
|
|
40
|
-
const axios_1 = __importStar(require("axios"));
|
|
41
|
-
/**
|
|
42
|
-
* Validate JWT token by making a test request to SAP system
|
|
43
|
-
* @param token JWT token to validate
|
|
44
|
-
* @param sapUrl SAP system URL
|
|
45
|
-
* @returns true if token is valid, false if expired/invalid
|
|
46
|
-
*/
|
|
47
|
-
async function validateToken(token, sapUrl) {
|
|
48
|
-
try {
|
|
49
|
-
// Make a lightweight request to test token validity
|
|
50
|
-
// Using /sap/bc/adt/core/discovery as it's a simple endpoint
|
|
51
|
-
const testUrl = `${sapUrl}/sap/bc/adt/core/discovery`;
|
|
52
|
-
const response = await axios_1.default.get(testUrl, {
|
|
53
|
-
headers: {
|
|
54
|
-
'Authorization': `Bearer ${token}`,
|
|
55
|
-
'Accept': 'application/xml',
|
|
56
|
-
},
|
|
57
|
-
timeout: 10000, // 10 second timeout
|
|
58
|
-
validateStatus: (status) => status < 500, // Don't throw on 4xx errors
|
|
59
|
-
});
|
|
60
|
-
// 200-299: Token is valid
|
|
61
|
-
if (response.status >= 200 && response.status < 300) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
// 401/403: Token expired or invalid (but distinguish from permission errors)
|
|
65
|
-
if (response.status === 401 || response.status === 403) {
|
|
66
|
-
const responseText = typeof response.data === 'string'
|
|
67
|
-
? response.data
|
|
68
|
-
: JSON.stringify(response.data || '');
|
|
69
|
-
// Check if it's a permission error (not auth error)
|
|
70
|
-
if (responseText.includes('ExceptionResourceNoAccess') ||
|
|
71
|
-
responseText.includes('No authorization') ||
|
|
72
|
-
responseText.includes('Missing authorization')) {
|
|
73
|
-
// Permission error - token is valid but user doesn't have access
|
|
74
|
-
// We consider this as valid token
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
// Auth error - token expired or invalid
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
// Other errors - assume token is valid (might be network issues, etc.)
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
if (error instanceof axios_1.AxiosError) {
|
|
85
|
-
// Network errors or timeouts - assume token might be valid
|
|
86
|
-
// (we don't want to invalidate tokens due to network issues)
|
|
87
|
-
if (error.code === 'ECONNABORTED' || error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
|
|
88
|
-
// Network issue - assume token is valid
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
// 401/403 errors
|
|
92
|
-
if (error.response?.status === 401 || error.response?.status === 403) {
|
|
93
|
-
const responseText = typeof error.response.data === 'string'
|
|
94
|
-
? error.response.data
|
|
95
|
-
: JSON.stringify(error.response.data || '');
|
|
96
|
-
// Check if it's a permission error
|
|
97
|
-
if (responseText.includes('ExceptionResourceNoAccess') ||
|
|
98
|
-
responseText.includes('No authorization') ||
|
|
99
|
-
responseText.includes('Missing authorization')) {
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Unknown error - assume token is valid to avoid false negatives
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
}
|