@dataflint/mcp-server 1.0.15 → 1.0.21
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/dist/auth/auth0-service.d.ts.map +1 -1
- package/dist/auth/auth0-service.js +27 -13
- package/dist/auth/auth0-service.js.map +1 -1
- package/dist/auth/errors.d.ts +86 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +144 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +10 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/secrets/aws-secrets-provider.d.ts.map +1 -1
- package/dist/auth/secrets/aws-secrets-provider.js +3 -1
- package/dist/auth/secrets/aws-secrets-provider.js.map +1 -1
- package/dist/dataflint-server-service.d.ts +7 -2
- package/dist/dataflint-server-service.d.ts.map +1 -1
- package/dist/dataflint-server-service.js +86 -15
- package/dist/dataflint-server-service.js.map +1 -1
- package/dist/errors.d.ts +55 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +185 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -9
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/standalone/config.js +1667 -280
- package/dist/standalone/config.js.map +7 -1
- package/dist/standalone/logger.js +2 -2
- package/dist/standalone/logger.js.map +1 -1
- package/dist/standalone/server.js +3 -3
- package/dist/standalone/server.js.map +1 -1
- package/dist/standalone/stdio-transport.d.ts +1 -1
- package/dist/standalone/stdio-transport.d.ts.map +1 -1
- package/dist/standalone/stdio-transport.js +2 -2
- package/dist/standalone/stdio-transport.js.map +1 -1
- package/dist/test-helpers.d.ts +27 -0
- package/dist/test-helpers.d.ts.map +1 -0
- package/dist/test-helpers.js +101 -0
- package/dist/test-helpers.js.map +1 -0
- package/dist/tools/base.d.ts +16 -0
- package/dist/tools/base.d.ts.map +1 -1
- package/dist/tools/base.js +16 -0
- package/dist/tools/base.js.map +1 -1
- package/dist/tools/core-tools.d.ts.map +1 -1
- package/dist/tools/core-tools.js +4 -4
- package/dist/tools/core-tools.js.map +1 -1
- package/dist/tools/expertise-tools.d.ts.map +1 -1
- package/dist/tools/expertise-tools.js +5 -5
- package/dist/tools/expertise-tools.js.map +1 -1
- package/dist/tools/findings-tools.d.ts.map +1 -1
- package/dist/tools/findings-tools.js +4 -4
- package/dist/tools/findings-tools.js.map +1 -1
- package/dist/tools/highlight-tools.d.ts.map +1 -1
- package/dist/tools/highlight-tools.js +8 -10
- package/dist/tools/highlight-tools.js.map +1 -1
- package/dist/tools/listing-tools.d.ts.map +1 -1
- package/dist/tools/listing-tools.js +1 -1
- package/dist/tools/listing-tools.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
|
@@ -1,317 +1,1704 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
|
|
28
|
+
// dist/auth/customer-auth-configs.js
|
|
29
|
+
var require_customer_auth_configs = __commonJS({
|
|
30
|
+
"dist/auth/customer-auth-configs.js"(exports2) {
|
|
31
|
+
"use strict";
|
|
32
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
33
|
+
exports2.customerAuthConfigs = void 0;
|
|
34
|
+
exports2.customerAuthConfigs = {
|
|
35
|
+
// Customer domain hash → Auth0 configuration
|
|
36
|
+
"857064adfec4e0e5e37be8afef397155db006bb6009d1b395388d9174eb40795": {
|
|
37
|
+
clientId: "CWvpqujjEV2aoRSDVWFSh1U6HQALygB0",
|
|
38
|
+
domainProducer: (customerDomain) => `https://dataflint-${customerDomain}.us.auth0.com/`
|
|
39
|
+
},
|
|
40
|
+
cafe6e0af028d729afd3c4a386482621af90e8e117b1216f2bbc08e86a5e9445: {
|
|
41
|
+
clientId: "HRLICLhE0BP4AeZ8dSPAoDHFmMZVacxi"
|
|
42
|
+
},
|
|
43
|
+
"1613f29ea956158d2ad56a10780feb45d78755819565e76c4bf0d9069d17aab9": {
|
|
44
|
+
clientId: "CnyJJKVqes0Y0uU57GreAeaPbJlm4l4w"
|
|
45
|
+
},
|
|
46
|
+
eae8e3404182477f008479b38a6629ee86b23cefe2c418c5dc5c2f0d02af5475: {
|
|
47
|
+
clientId: "etY3z44ssWohe77PEBIMPzktW4BmvWGT"
|
|
48
|
+
},
|
|
49
|
+
// dataflint-demo (added from commit f38928c)
|
|
50
|
+
cc1677626e05d82b301cc83c22a850eac849555e704f288083108d79f600cea1: {
|
|
51
|
+
clientId: "u9W23NGvlV58W2N9WXMMhsM12bKK8oGI"
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// dist/auth/types.js
|
|
58
|
+
var require_types = __commonJS({
|
|
59
|
+
"dist/auth/types.js"(exports2) {
|
|
60
|
+
"use strict";
|
|
61
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
62
|
+
exports2.M2MType = exports2.AuthStrategyType = void 0;
|
|
63
|
+
var AuthStrategyType;
|
|
64
|
+
(function(AuthStrategyType2) {
|
|
65
|
+
AuthStrategyType2["SERVICE_ACCOUNT"] = "service_account";
|
|
66
|
+
AuthStrategyType2["AUTH0_M2M"] = "auth0_m2m";
|
|
67
|
+
AuthStrategyType2["AUTH0_USER"] = "auth0_user";
|
|
68
|
+
})(AuthStrategyType || (exports2.AuthStrategyType = AuthStrategyType = {}));
|
|
69
|
+
var M2MType;
|
|
70
|
+
(function(M2MType2) {
|
|
71
|
+
M2MType2["NONE"] = "none";
|
|
72
|
+
M2MType2["SERVICE_ACCOUNT"] = "service_account";
|
|
73
|
+
M2MType2["AUTH0_M2M"] = "auth0_m2m";
|
|
74
|
+
})(M2MType || (exports2.M2MType = M2MType = {}));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// dist/auth/errors.js
|
|
79
|
+
var require_errors = __commonJS({
|
|
80
|
+
"dist/auth/errors.js"(exports2) {
|
|
81
|
+
"use strict";
|
|
82
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
83
|
+
exports2.NetworkError = exports2.ConfigError = exports2.AuthError = exports2.DataFlintError = exports2.ErrorCode = void 0;
|
|
84
|
+
var ErrorCode;
|
|
85
|
+
(function(ErrorCode2) {
|
|
86
|
+
ErrorCode2["AUTH_NOT_INITIALIZED"] = "AUTH_NOT_INITIALIZED";
|
|
87
|
+
ErrorCode2["AUTH_TOKEN_EXPIRED"] = "AUTH_TOKEN_EXPIRED";
|
|
88
|
+
ErrorCode2["AUTH_TOKEN_INVALID"] = "AUTH_TOKEN_INVALID";
|
|
89
|
+
ErrorCode2["AUTH_REFRESH_FAILED"] = "AUTH_REFRESH_FAILED";
|
|
90
|
+
ErrorCode2["AUTH_LOGIN_REQUIRED"] = "AUTH_LOGIN_REQUIRED";
|
|
91
|
+
ErrorCode2["AUTH_TIMEOUT"] = "AUTH_TIMEOUT";
|
|
92
|
+
ErrorCode2["CONFIG_MISSING"] = "CONFIG_MISSING";
|
|
93
|
+
ErrorCode2["CONFIG_INVALID"] = "CONFIG_INVALID";
|
|
94
|
+
ErrorCode2["CONFIG_DOMAIN_NOT_FOUND"] = "CONFIG_DOMAIN_NOT_FOUND";
|
|
95
|
+
ErrorCode2["NETWORK_UNAVAILABLE"] = "NETWORK_UNAVAILABLE";
|
|
96
|
+
ErrorCode2["NETWORK_TIMEOUT"] = "NETWORK_TIMEOUT";
|
|
97
|
+
ErrorCode2["NETWORK_DNS_FAILED"] = "NETWORK_DNS_FAILED";
|
|
98
|
+
ErrorCode2["API_UNAUTHORIZED"] = "API_UNAUTHORIZED";
|
|
99
|
+
ErrorCode2["API_FORBIDDEN"] = "API_FORBIDDEN";
|
|
100
|
+
ErrorCode2["API_NOT_FOUND"] = "API_NOT_FOUND";
|
|
101
|
+
ErrorCode2["API_RATE_LIMITED"] = "API_RATE_LIMITED";
|
|
102
|
+
ErrorCode2["API_SERVER_ERROR"] = "API_SERVER_ERROR";
|
|
103
|
+
ErrorCode2["API_BAD_REQUEST"] = "API_BAD_REQUEST";
|
|
104
|
+
ErrorCode2["SERVICE_NOT_STARTED"] = "SERVICE_NOT_STARTED";
|
|
105
|
+
ErrorCode2["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
|
106
|
+
ErrorCode2["UNKNOWN"] = "UNKNOWN";
|
|
107
|
+
})(ErrorCode || (exports2.ErrorCode = ErrorCode = {}));
|
|
108
|
+
var DataFlintError = class extends Error {
|
|
109
|
+
cause;
|
|
110
|
+
constructor(message, cause) {
|
|
111
|
+
super(message);
|
|
112
|
+
this.cause = cause;
|
|
113
|
+
this.name = this.constructor.name;
|
|
114
|
+
if (Error.captureStackTrace) {
|
|
115
|
+
Error.captureStackTrace(this, this.constructor);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get a user-friendly error message with action
|
|
120
|
+
*/
|
|
121
|
+
getUserMessage() {
|
|
122
|
+
return `${this.message}. ${this.userAction}`;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
exports2.DataFlintError = DataFlintError;
|
|
126
|
+
var AuthError = class _AuthError extends DataFlintError {
|
|
127
|
+
code;
|
|
128
|
+
isRetryable;
|
|
129
|
+
userAction;
|
|
130
|
+
constructor(code, message, userAction, isRetryable = false, cause) {
|
|
131
|
+
super(message, cause);
|
|
132
|
+
this.code = code;
|
|
133
|
+
this.isRetryable = isRetryable;
|
|
134
|
+
this.userAction = userAction;
|
|
135
|
+
}
|
|
136
|
+
static tokenExpired(cause) {
|
|
137
|
+
return new _AuthError(ErrorCode.AUTH_TOKEN_EXPIRED, "Your session has expired", 'Please click "Login" to authenticate again.', false, cause);
|
|
138
|
+
}
|
|
139
|
+
static tokenInvalid(cause) {
|
|
140
|
+
return new _AuthError(ErrorCode.AUTH_TOKEN_INVALID, "Authentication token is invalid", 'Please click "Login" to authenticate again.', false, cause);
|
|
141
|
+
}
|
|
142
|
+
static refreshFailed(cause) {
|
|
143
|
+
return new _AuthError(ErrorCode.AUTH_REFRESH_FAILED, "Failed to refresh authentication", 'Please click "Login" to authenticate again.', false, cause);
|
|
144
|
+
}
|
|
145
|
+
static loginRequired() {
|
|
146
|
+
return new _AuthError(ErrorCode.AUTH_LOGIN_REQUIRED, "Authentication required", 'Please run "DataFlint: Login" from the command palette.', false);
|
|
147
|
+
}
|
|
148
|
+
static timeout(cause) {
|
|
149
|
+
return new _AuthError(ErrorCode.AUTH_TIMEOUT, "Authentication timed out", "Please check your internet connection and try again.", true, cause);
|
|
150
|
+
}
|
|
151
|
+
static notInitialized() {
|
|
152
|
+
return new _AuthError(ErrorCode.AUTH_NOT_INITIALIZED, "Authentication service not initialized", 'Please run "DataFlint: Restart Server" to reinitialize.', true);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
exports2.AuthError = AuthError;
|
|
156
|
+
var ConfigError = class _ConfigError extends DataFlintError {
|
|
157
|
+
code;
|
|
158
|
+
isRetryable = false;
|
|
159
|
+
userAction;
|
|
160
|
+
constructor(code, message, userAction, cause) {
|
|
161
|
+
super(message, cause);
|
|
162
|
+
this.code = code;
|
|
163
|
+
this.userAction = userAction;
|
|
164
|
+
}
|
|
165
|
+
static missing(field) {
|
|
166
|
+
return new _ConfigError(ErrorCode.CONFIG_MISSING, `Missing required configuration: ${field}`, 'Please check your DataFlint settings. Run "DataFlint: Show Debug Information" for details.');
|
|
167
|
+
}
|
|
168
|
+
static invalid(field, value, expected) {
|
|
169
|
+
return new _ConfigError(ErrorCode.CONFIG_INVALID, `Invalid configuration for ${field}: "${value}"`, `Expected ${expected}. Please check your DataFlint settings.`);
|
|
170
|
+
}
|
|
171
|
+
static customerDomainNotFound(domain) {
|
|
172
|
+
return new _ConfigError(ErrorCode.CONFIG_DOMAIN_NOT_FOUND, `Customer domain "${domain}" is not configured`, "Please contact support to set up your organization's domain, or remove the customer domain setting.");
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
exports2.ConfigError = ConfigError;
|
|
176
|
+
var NetworkError = class _NetworkError extends DataFlintError {
|
|
177
|
+
code;
|
|
178
|
+
isRetryable = true;
|
|
179
|
+
userAction;
|
|
180
|
+
constructor(code, message, userAction, cause) {
|
|
181
|
+
super(message, cause);
|
|
182
|
+
this.code = code;
|
|
183
|
+
this.userAction = userAction;
|
|
184
|
+
}
|
|
185
|
+
static unavailable(cause) {
|
|
186
|
+
return new _NetworkError(ErrorCode.NETWORK_UNAVAILABLE, "Cannot connect to server", "Please check your internet connection and try again.", cause);
|
|
187
|
+
}
|
|
188
|
+
static timeout(cause) {
|
|
189
|
+
return new _NetworkError(ErrorCode.NETWORK_TIMEOUT, "Request timed out", "The server took too long to respond. Please check your connection and try again.", cause);
|
|
190
|
+
}
|
|
191
|
+
static dnsFailed(host, cause) {
|
|
192
|
+
return new _NetworkError(ErrorCode.NETWORK_DNS_FAILED, `Cannot resolve hostname: ${host}`, "Please check your internet connection and DNS settings.", cause);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
exports2.NetworkError = NetworkError;
|
|
196
|
+
}
|
|
17
197
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
198
|
+
|
|
199
|
+
// dist/auth/auth0-service.js
|
|
200
|
+
var require_auth0_service = __commonJS({
|
|
201
|
+
"dist/auth/auth0-service.js"(exports2) {
|
|
202
|
+
"use strict";
|
|
203
|
+
var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
204
|
+
if (k2 === void 0) k2 = k;
|
|
205
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
206
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
207
|
+
desc = { enumerable: true, get: function() {
|
|
208
|
+
return m[k];
|
|
209
|
+
} };
|
|
210
|
+
}
|
|
211
|
+
Object.defineProperty(o, k2, desc);
|
|
212
|
+
}) : (function(o, m, k, k2) {
|
|
213
|
+
if (k2 === void 0) k2 = k;
|
|
214
|
+
o[k2] = m[k];
|
|
215
|
+
}));
|
|
216
|
+
var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
217
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
218
|
+
}) : function(o, v) {
|
|
219
|
+
o["default"] = v;
|
|
220
|
+
});
|
|
221
|
+
var __importStar2 = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
222
|
+
var ownKeys = function(o) {
|
|
223
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
224
|
+
var ar = [];
|
|
225
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
226
|
+
return ar;
|
|
24
227
|
};
|
|
25
228
|
return ownKeys(o);
|
|
26
|
-
|
|
27
|
-
|
|
229
|
+
};
|
|
230
|
+
return function(mod) {
|
|
28
231
|
if (mod && mod.__esModule) return mod;
|
|
29
232
|
var result = {};
|
|
30
|
-
if (mod != null)
|
|
31
|
-
|
|
233
|
+
if (mod != null) {
|
|
234
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding2(result, mod, k[i]);
|
|
235
|
+
}
|
|
236
|
+
__setModuleDefault2(result, mod);
|
|
32
237
|
return result;
|
|
238
|
+
};
|
|
239
|
+
})();
|
|
240
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
241
|
+
exports2.Auth0Service = void 0;
|
|
242
|
+
var http = __importStar2(require("http"));
|
|
243
|
+
var openid_client_1 = require("openid-client");
|
|
244
|
+
var url_1 = require("url");
|
|
245
|
+
var errors_1 = require_errors();
|
|
246
|
+
var AUTH_DISCOVERY_TIMEOUT_MS = 1e4;
|
|
247
|
+
openid_client_1.custom.setHttpOptionsDefaults({
|
|
248
|
+
timeout: AUTH_DISCOVERY_TIMEOUT_MS
|
|
249
|
+
});
|
|
250
|
+
var noopLogger = {
|
|
251
|
+
info: () => {
|
|
252
|
+
},
|
|
253
|
+
warn: () => {
|
|
254
|
+
},
|
|
255
|
+
error: () => {
|
|
256
|
+
},
|
|
257
|
+
debug: () => {
|
|
258
|
+
}
|
|
33
259
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
authDomain: zod_1.z.string().optional(),
|
|
62
|
-
clientId: zod_1.z.string().optional(),
|
|
63
|
-
audience: zod_1.z.string().optional(),
|
|
64
|
-
scope: zod_1.z.string().optional(),
|
|
65
|
-
credentialsPath: zod_1.z.string().optional(),
|
|
66
|
-
adminCompanyDomain: zod_1.z.string().optional(),
|
|
67
|
-
customerDomain: zod_1.z.string().optional(),
|
|
68
|
-
m2mTokenPath: zod_1.z.string().optional(),
|
|
69
|
-
m2mSecretName: zod_1.z.string().optional(),
|
|
70
|
-
tenantId: zod_1.z.string().optional(),
|
|
71
|
-
})
|
|
72
|
-
.strict();
|
|
73
|
-
class StandaloneConfigService {
|
|
74
|
-
config;
|
|
75
|
-
credentialsPath;
|
|
76
|
-
m2mMode;
|
|
77
|
-
constructor(config = {}) {
|
|
78
|
-
this.config = this.mergeWithDefaults(config);
|
|
79
|
-
this.m2mMode = this.detectM2MMode();
|
|
80
|
-
this.validateM2MConfig();
|
|
81
|
-
this.credentialsPath =
|
|
82
|
-
config.credentialsPath || this.defaultCredentialsPath();
|
|
83
|
-
this.ensureDataflintDirectory();
|
|
84
|
-
}
|
|
85
|
-
defaultCredentialsPath() {
|
|
86
|
-
const hash = crypto
|
|
87
|
-
.createHash("sha256")
|
|
88
|
-
.update(this.config.clientId || DEFAULT_CLIENT_ID_FOR_HASH)
|
|
89
|
-
.digest("hex")
|
|
90
|
-
.substring(0, HASH_PREFIX_LENGTH);
|
|
91
|
-
return path.join(os.homedir(), ".dataflint", `credentials-${hash}.json`);
|
|
92
|
-
}
|
|
93
|
-
ensureDataflintDirectory() {
|
|
94
|
-
const dir = path.dirname(this.credentialsPath);
|
|
95
|
-
if (!fs.existsSync(dir)) {
|
|
96
|
-
fs.mkdirSync(dir, { recursive: true, mode: CREDENTIALS_DIR_MODE });
|
|
260
|
+
var Auth0Service = class {
|
|
261
|
+
config;
|
|
262
|
+
redirectUri;
|
|
263
|
+
callbackPort;
|
|
264
|
+
client = null;
|
|
265
|
+
issuer = null;
|
|
266
|
+
initialized = false;
|
|
267
|
+
openUrlHandler;
|
|
268
|
+
logger;
|
|
269
|
+
constructor(openUrlHandler, configProvider, logger, callbackPort = 11334) {
|
|
270
|
+
this.logger = logger || noopLogger;
|
|
271
|
+
this.openUrlHandler = openUrlHandler;
|
|
272
|
+
this.config = {
|
|
273
|
+
...configProvider(),
|
|
274
|
+
scope: configProvider().scope || "openid profile email"
|
|
275
|
+
};
|
|
276
|
+
this.callbackPort = callbackPort;
|
|
277
|
+
this.redirectUri = `http://localhost:${callbackPort}/callback`;
|
|
278
|
+
this.logger.info(`Auth0Service initialized for domain: ${this.config.domain}`);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Initialize the Auth0 client by discovering the issuer metadata
|
|
282
|
+
*/
|
|
283
|
+
async initialize() {
|
|
284
|
+
if (this.initialized) {
|
|
285
|
+
this.logger.debug("Auth0 client already initialized");
|
|
286
|
+
return;
|
|
97
287
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
288
|
+
try {
|
|
289
|
+
const issuerUrl = this.config.domain.startsWith("http") ? this.config.domain : `https://${this.config.domain}`;
|
|
290
|
+
this.logger.info(`Attempting to discover Auth0 issuer at: ${issuerUrl}`);
|
|
291
|
+
this.logger.debug(`Discovery URL will be: ${issuerUrl}`);
|
|
292
|
+
this.issuer = await openid_client_1.Issuer.discover(issuerUrl);
|
|
293
|
+
this.logger.info(`Auth0 issuer discovered successfully: ${this.issuer.issuer}`);
|
|
294
|
+
this.client = new this.issuer.Client({
|
|
295
|
+
client_id: this.config.clientId,
|
|
296
|
+
redirect_uris: [this.redirectUri],
|
|
297
|
+
response_types: ["code"],
|
|
298
|
+
token_endpoint_auth_method: "none"
|
|
299
|
+
// Public client, no client secret required
|
|
300
|
+
});
|
|
301
|
+
this.initialized = true;
|
|
302
|
+
this.logger.info("Auth0 client initialized successfully");
|
|
303
|
+
} catch (error) {
|
|
304
|
+
this.logger.error("Failed to initialize Auth0 client", error);
|
|
305
|
+
this.logger.error(`Auth0 domain: ${this.config.domain}`);
|
|
306
|
+
this.logger.error(`Client ID: ${this.config.clientId}`);
|
|
307
|
+
this.logger.error(`Constructed issuer URL: ${this.config.domain.startsWith("http") ? this.config.domain : `https://${this.config.domain}`}`);
|
|
308
|
+
if (error instanceof Error) {
|
|
309
|
+
const message = error.message.toLowerCase();
|
|
310
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
311
|
+
throw errors_1.ConfigError.invalid("Auth0 domain", this.config.domain, "a valid Auth0 domain (e.g., your-tenant.auth0.com)");
|
|
312
|
+
}
|
|
313
|
+
if (message.includes("enotfound") || message.includes("getaddrinfo")) {
|
|
314
|
+
throw errors_1.NetworkError.dnsFailed(this.config.domain, error);
|
|
315
|
+
}
|
|
316
|
+
if (message.includes("timeout") || message.includes("etimedout")) {
|
|
317
|
+
throw errors_1.AuthError.timeout(error);
|
|
318
|
+
}
|
|
319
|
+
if (message.includes("econnrefused") || message.includes("econnreset")) {
|
|
320
|
+
throw errors_1.NetworkError.unavailable(error);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
throw new errors_1.AuthError("AUTH_NOT_INITIALIZED", `Auth0 initialization failed: ${error instanceof Error ? error.message : String(error)}`, "Please check your internet connection and Auth0 configuration.", false, error instanceof Error ? error : void 0);
|
|
117
324
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Start the authentication flow
|
|
328
|
+
*/
|
|
329
|
+
async authenticate() {
|
|
330
|
+
if (!this.client) {
|
|
331
|
+
await this.initialize();
|
|
123
332
|
}
|
|
124
|
-
|
|
333
|
+
if (!this.client) {
|
|
334
|
+
throw errors_1.AuthError.notInitialized();
|
|
335
|
+
}
|
|
336
|
+
const codeVerifier = openid_client_1.generators.codeVerifier();
|
|
337
|
+
const codeChallenge = openid_client_1.generators.codeChallenge(codeVerifier);
|
|
338
|
+
const authUrl = this.client.authorizationUrl({
|
|
339
|
+
scope: this.config.scope,
|
|
340
|
+
code_challenge: codeChallenge,
|
|
341
|
+
code_challenge_method: "S256",
|
|
342
|
+
...this.config.audience && { audience: this.config.audience }
|
|
343
|
+
});
|
|
344
|
+
this.logger.info("Opening browser for authentication...");
|
|
125
345
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
346
|
+
await this.openUrlHandler(authUrl);
|
|
347
|
+
} catch (error) {
|
|
348
|
+
this.logger.error("Failed to open browser", error);
|
|
349
|
+
this.logger.info(`Please manually navigate to: ${authUrl}`);
|
|
350
|
+
}
|
|
351
|
+
return new Promise((resolve, reject) => {
|
|
352
|
+
const server = http.createServer(async (req, res) => {
|
|
353
|
+
var _a;
|
|
354
|
+
try {
|
|
355
|
+
if (!((_a = req.url) == null ? void 0 : _a.startsWith("/callback"))) {
|
|
356
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
357
|
+
res.end("Not Found");
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const callbackUrl = new url_1.URL(`http://localhost:${this.callbackPort}${req.url}`);
|
|
361
|
+
const params = this.client.callbackParams(callbackUrl.toString());
|
|
362
|
+
const tokenSet = await this.client.callback(this.redirectUri, params, {
|
|
363
|
+
code_verifier: codeVerifier
|
|
364
|
+
});
|
|
365
|
+
const authResult = this.processTokenSet(tokenSet);
|
|
366
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
367
|
+
res.end(`
|
|
368
|
+
<html>
|
|
369
|
+
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
|
|
370
|
+
<h2 style="color: #4CAF50;">Authentication Successful!</h2>
|
|
371
|
+
<p>You can now close this tab and return to VS Code/Cursor.</p>
|
|
372
|
+
<script>
|
|
373
|
+
setTimeout(() => {
|
|
374
|
+
window.close();
|
|
375
|
+
}, 3000);
|
|
376
|
+
</script>
|
|
377
|
+
</body>
|
|
378
|
+
</html>
|
|
379
|
+
`);
|
|
380
|
+
server.close();
|
|
381
|
+
resolve(authResult);
|
|
382
|
+
} catch (error) {
|
|
383
|
+
this.logger.error("Authentication callback error", error);
|
|
384
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
385
|
+
res.end(`
|
|
386
|
+
<html>
|
|
387
|
+
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
|
|
388
|
+
<h2 style="color: #f44336;">Authentication Failed</h2>
|
|
389
|
+
<p>Error: ${error}</p>
|
|
390
|
+
<p>Please try again.</p>
|
|
391
|
+
</body>
|
|
392
|
+
</html>
|
|
393
|
+
`);
|
|
394
|
+
server.close();
|
|
395
|
+
reject(error);
|
|
131
396
|
}
|
|
132
|
-
|
|
397
|
+
});
|
|
398
|
+
server.listen(this.callbackPort, () => {
|
|
399
|
+
this.logger.info(`Listening for Auth0 callback on http://localhost:${this.callbackPort}/callback`);
|
|
400
|
+
});
|
|
401
|
+
setTimeout(() => {
|
|
402
|
+
server.close();
|
|
403
|
+
reject(errors_1.AuthError.timeout());
|
|
404
|
+
}, 3e5);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Get user information using the access token
|
|
409
|
+
*/
|
|
410
|
+
async getUserInfo(accessToken) {
|
|
411
|
+
if (!this.client) {
|
|
412
|
+
throw errors_1.AuthError.notInitialized();
|
|
133
413
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
414
|
+
try {
|
|
415
|
+
this.logger.info("Fetching user information...");
|
|
416
|
+
const userInfo = await this.client.userinfo(accessToken);
|
|
417
|
+
this.logger.info("User information retrieved successfully");
|
|
418
|
+
this.logger.debug(`User ID: ${userInfo.sub}`);
|
|
419
|
+
return userInfo;
|
|
420
|
+
} catch (error) {
|
|
421
|
+
this.logger.error("Failed to get user info", error);
|
|
422
|
+
throw error;
|
|
137
423
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Refresh the access token using refresh token
|
|
427
|
+
*/
|
|
428
|
+
async refreshToken(refreshToken) {
|
|
429
|
+
if (!this.client) {
|
|
430
|
+
throw errors_1.AuthError.notInitialized();
|
|
431
|
+
}
|
|
432
|
+
try {
|
|
433
|
+
this.logger.info("Refreshing access token...");
|
|
434
|
+
const tokenSet = await this.client.refresh(refreshToken);
|
|
435
|
+
const result = this.processTokenSet(tokenSet);
|
|
436
|
+
this.logger.info("Token refresh completed successfully");
|
|
437
|
+
return result;
|
|
438
|
+
} catch (error) {
|
|
439
|
+
this.logger.error("Token refresh failed", error);
|
|
440
|
+
throw error;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Process token set and return structured result
|
|
445
|
+
*/
|
|
446
|
+
processTokenSet(tokenSet) {
|
|
447
|
+
var _a;
|
|
448
|
+
const result = {
|
|
449
|
+
accessToken: tokenSet.access_token,
|
|
450
|
+
idToken: tokenSet.id_token,
|
|
451
|
+
refreshToken: tokenSet.refresh_token
|
|
151
452
|
};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
scope: DEFAULT_SCOPE,
|
|
179
|
-
// Credentials path only configurable via CLI argument for security
|
|
180
|
-
credentialsPath: config.credentialsPath,
|
|
181
|
-
adminCompanyDomain: config.adminCompanyDomain ||
|
|
182
|
-
envConfig.adminCompanyDomain ||
|
|
183
|
-
fileConfig.adminCompanyDomain ||
|
|
184
|
-
DEFAULT_ADMIN_COMPANY_DOMAIN,
|
|
185
|
-
customerDomain: customerDomain,
|
|
186
|
-
m2mTokenPath: config.m2mTokenPath ||
|
|
187
|
-
envConfig.m2mTokenPath ||
|
|
188
|
-
fileConfig.m2mTokenPath,
|
|
189
|
-
m2mSecretName: config.m2mSecretName ||
|
|
190
|
-
envConfig.m2mSecretName ||
|
|
191
|
-
fileConfig.m2mSecretName,
|
|
192
|
-
tenantId: config.tenantId ||
|
|
193
|
-
envConfig.tenantId ||
|
|
194
|
-
fileConfig.tenantId,
|
|
195
|
-
};
|
|
453
|
+
if (tokenSet.expires_at) {
|
|
454
|
+
result.expiresAt = new Date(tokenSet.expires_at * 1e3);
|
|
455
|
+
}
|
|
456
|
+
this.logger.info("Authentication tokens processed successfully");
|
|
457
|
+
this.logger.debug(`Access Token: ${(_a = result.accessToken) == null ? void 0 : _a.substring(0, 20)}...`);
|
|
458
|
+
this.logger.debug(`ID Token: ${result.idToken ? "Present" : "Not provided"}`);
|
|
459
|
+
this.logger.debug(`Refresh Token: ${result.refreshToken ? "Present" : "Not provided"}`);
|
|
460
|
+
this.logger.debug(`Expires At: ${result.expiresAt}`);
|
|
461
|
+
return result;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Check if a token is expired
|
|
465
|
+
*/
|
|
466
|
+
isTokenExpired(authResult) {
|
|
467
|
+
if (!authResult.expiresAt) {
|
|
468
|
+
this.logger.debug("No expiration time available, considering token valid");
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
const expiresAt = authResult.expiresAt instanceof Date ? authResult.expiresAt : new Date(authResult.expiresAt);
|
|
472
|
+
const now = /* @__PURE__ */ new Date();
|
|
473
|
+
const buffer = 5 * 60 * 1e3;
|
|
474
|
+
const isExpired = expiresAt.getTime() - buffer < now.getTime();
|
|
475
|
+
if (isExpired) {
|
|
476
|
+
this.logger.warn("Access token is expired or will expire soon");
|
|
477
|
+
} else {
|
|
478
|
+
this.logger.debug("Access token is still valid");
|
|
196
479
|
}
|
|
197
|
-
|
|
198
|
-
|
|
480
|
+
return isExpired;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Logout (revoke tokens if supported)
|
|
484
|
+
*/
|
|
485
|
+
async logout(accessToken) {
|
|
486
|
+
if (!this.client) {
|
|
487
|
+
throw errors_1.AuthError.notInitialized();
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
await this.client.revoke(accessToken);
|
|
491
|
+
this.logger.info("Token revoked successfully");
|
|
492
|
+
} catch (error) {
|
|
493
|
+
this.logger.error("Failed to revoke token", error);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
exports2.Auth0Service = Auth0Service;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// dist/auth/auth0-m2m-service.js
|
|
502
|
+
var require_auth0_m2m_service = __commonJS({
|
|
503
|
+
"dist/auth/auth0-m2m-service.js"(exports2) {
|
|
504
|
+
"use strict";
|
|
505
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
506
|
+
exports2.Auth0M2MService = void 0;
|
|
507
|
+
var types_12 = require_types();
|
|
508
|
+
var noopLogger = {
|
|
509
|
+
info: () => {
|
|
510
|
+
},
|
|
511
|
+
warn: () => {
|
|
512
|
+
},
|
|
513
|
+
error: () => {
|
|
514
|
+
},
|
|
515
|
+
debug: () => {
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
var Auth0M2MService = class _Auth0M2MService {
|
|
519
|
+
credentials;
|
|
520
|
+
tenantId;
|
|
521
|
+
tokenCache = null;
|
|
522
|
+
logger;
|
|
523
|
+
initialized = false;
|
|
524
|
+
/**
|
|
525
|
+
* Token expiry buffer in milliseconds (5 minutes)
|
|
526
|
+
* Tokens will be refreshed this long before actual expiration
|
|
527
|
+
*/
|
|
528
|
+
static EXPIRY_BUFFER_MS = 5 * 60 * 1e3;
|
|
529
|
+
constructor(credentials, tenantId, logger) {
|
|
530
|
+
this.credentials = credentials;
|
|
531
|
+
this.tenantId = tenantId;
|
|
532
|
+
this.logger = logger || noopLogger;
|
|
533
|
+
const clientIdPrefix = credentials.client_id.substring(0, 8);
|
|
534
|
+
this.logger.info(`Auth0M2MService created for client: ${clientIdPrefix}...`);
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Get the strategy type identifier
|
|
538
|
+
*/
|
|
539
|
+
getType() {
|
|
540
|
+
return types_12.AuthStrategyType.AUTH0_M2M;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Initialize the M2M service
|
|
544
|
+
* Validates credentials format and performs initial token fetch
|
|
545
|
+
*/
|
|
546
|
+
async initialize() {
|
|
547
|
+
if (this.initialized) {
|
|
548
|
+
this.logger.debug("Auth0M2MService already initialized");
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
this.logger.info("Initializing Auth0M2MService...");
|
|
552
|
+
if (!this.credentials.client_id || !this.credentials.client_secret) {
|
|
553
|
+
throw new Error("M2M credentials missing client_id or client_secret");
|
|
554
|
+
}
|
|
555
|
+
if (!this.credentials.domain) {
|
|
556
|
+
throw new Error("M2M credentials missing domain");
|
|
557
|
+
}
|
|
558
|
+
if (!this.credentials.audience) {
|
|
559
|
+
throw new Error("M2M credentials missing audience");
|
|
560
|
+
}
|
|
561
|
+
await this.fetchNewToken();
|
|
562
|
+
this.initialized = true;
|
|
563
|
+
this.logger.info("Auth0M2MService initialized successfully");
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Get a valid access token, fetching a new one if cache is expired
|
|
567
|
+
*/
|
|
568
|
+
async getToken() {
|
|
569
|
+
const now = Date.now();
|
|
570
|
+
if (this.tokenCache && now < this.tokenCache.expiresAt - _Auth0M2MService.EXPIRY_BUFFER_MS) {
|
|
571
|
+
this.logger.debug("Using cached M2M token");
|
|
572
|
+
return this.tokenCache.accessToken;
|
|
573
|
+
}
|
|
574
|
+
this.logger.info("M2M token expired or not cached, fetching new token...");
|
|
575
|
+
await this.fetchNewToken();
|
|
576
|
+
return this.tokenCache.accessToken;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Force refresh the token by clearing cache and fetching a new one
|
|
580
|
+
*/
|
|
581
|
+
async refreshToken() {
|
|
582
|
+
this.logger.info("Force refreshing M2M token...");
|
|
583
|
+
this.tokenCache = null;
|
|
584
|
+
await this.fetchNewToken();
|
|
585
|
+
this.logger.info("M2M token refreshed");
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Check if currently authenticated (credentials are valid)
|
|
589
|
+
*/
|
|
590
|
+
async isAuthenticated() {
|
|
591
|
+
try {
|
|
592
|
+
await this.getToken();
|
|
593
|
+
return true;
|
|
594
|
+
} catch {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Get user information for the M2M client
|
|
600
|
+
* Returns synthetic user info since M2M clients don't have traditional user profiles
|
|
601
|
+
*/
|
|
602
|
+
async getUserInfo() {
|
|
603
|
+
const clientIdPrefix = this.credentials.client_id.substring(0, 8);
|
|
199
604
|
return {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
DEFAULT_SERVER_URL,
|
|
204
|
-
authDomain: config.authDomain ||
|
|
205
|
-
envConfig.authDomain ||
|
|
206
|
-
fileConfig.authDomain ||
|
|
207
|
-
DEFAULT_AUTH_DOMAIN,
|
|
208
|
-
clientId: config.clientId ||
|
|
209
|
-
envConfig.clientId ||
|
|
210
|
-
fileConfig.clientId ||
|
|
211
|
-
DEFAULT_PUBLIC_CLIENT_ID,
|
|
212
|
-
audience: config.audience ||
|
|
213
|
-
envConfig.audience ||
|
|
214
|
-
fileConfig.audience ||
|
|
215
|
-
DEFAULT_AUDIENCE,
|
|
216
|
-
scope: config.scope ||
|
|
217
|
-
envConfig.scope ||
|
|
218
|
-
fileConfig.scope ||
|
|
219
|
-
DEFAULT_SCOPE,
|
|
220
|
-
adminCompanyDomain: config.adminCompanyDomain ||
|
|
221
|
-
envConfig.adminCompanyDomain ||
|
|
222
|
-
fileConfig.adminCompanyDomain ||
|
|
223
|
-
DEFAULT_ADMIN_COMPANY_DOMAIN,
|
|
224
|
-
// Credentials path only configurable via CLI argument for security
|
|
225
|
-
credentialsPath: config.credentialsPath,
|
|
226
|
-
customerDomain: undefined,
|
|
227
|
-
m2mTokenPath: config.m2mTokenPath ||
|
|
228
|
-
envConfig.m2mTokenPath ||
|
|
229
|
-
fileConfig.m2mTokenPath,
|
|
230
|
-
m2mSecretName: config.m2mSecretName ||
|
|
231
|
-
envConfig.m2mSecretName ||
|
|
232
|
-
fileConfig.m2mSecretName,
|
|
233
|
-
tenantId: config.tenantId || envConfig.tenantId || fileConfig.tenantId,
|
|
605
|
+
sub: `m2m-client-${clientIdPrefix}`,
|
|
606
|
+
name: "M2M Client",
|
|
607
|
+
...this.tenantId && { tenant_id: this.tenantId }
|
|
234
608
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Get the tenant ID associated with this M2M client
|
|
612
|
+
*/
|
|
613
|
+
getTenantId() {
|
|
614
|
+
return this.tenantId;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Fetch a new token from Auth0 using client credentials grant
|
|
618
|
+
*/
|
|
619
|
+
async fetchNewToken() {
|
|
620
|
+
const domain = this.credentials.domain.startsWith("http") ? this.credentials.domain : `https://${this.credentials.domain}`;
|
|
621
|
+
const tokenUrl = `${domain.replace(/\/$/, "")}/oauth/token`;
|
|
622
|
+
this.logger.debug(`Fetching M2M token from: ${tokenUrl}`);
|
|
623
|
+
const requestBody = {
|
|
624
|
+
grant_type: "client_credentials",
|
|
625
|
+
client_id: this.credentials.client_id,
|
|
626
|
+
client_secret: this.credentials.client_secret,
|
|
627
|
+
audience: this.credentials.audience
|
|
628
|
+
};
|
|
629
|
+
try {
|
|
630
|
+
const response = await fetch(tokenUrl, {
|
|
631
|
+
method: "POST",
|
|
632
|
+
headers: {
|
|
633
|
+
"Content-Type": "application/json"
|
|
634
|
+
},
|
|
635
|
+
body: JSON.stringify(requestBody)
|
|
636
|
+
});
|
|
637
|
+
if (!response.ok) {
|
|
638
|
+
this.logger.error(`M2M token request failed: ${response.status}`);
|
|
639
|
+
throw new Error(`Auth0 M2M token request failed with status ${response.status}`);
|
|
640
|
+
}
|
|
641
|
+
const tokenResponse = await response.json();
|
|
642
|
+
if (!tokenResponse.access_token) {
|
|
643
|
+
throw new Error("Auth0 response missing access_token");
|
|
644
|
+
}
|
|
645
|
+
const expiresIn = tokenResponse.expires_in || 3600;
|
|
646
|
+
const expiresAt = Date.now() + expiresIn * 1e3;
|
|
647
|
+
this.tokenCache = {
|
|
648
|
+
accessToken: tokenResponse.access_token,
|
|
649
|
+
expiresAt
|
|
650
|
+
};
|
|
651
|
+
const expiresInMinutes = Math.floor(expiresIn / 60);
|
|
652
|
+
this.logger.info(`M2M token obtained${this.tenantId ? ` for tenant ${this.tenantId}` : ""}: expires in ${expiresInMinutes} minutes`);
|
|
653
|
+
} catch (error) {
|
|
654
|
+
this.tokenCache = null;
|
|
655
|
+
if (error instanceof Error) {
|
|
656
|
+
this.logger.error("Failed to fetch M2M token", error);
|
|
657
|
+
throw error;
|
|
658
|
+
}
|
|
659
|
+
throw new Error(`Failed to fetch M2M token: ${error}`);
|
|
240
660
|
}
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
exports2.Auth0M2MService = Auth0M2MService;
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
// dist/auth/service-account-service.js
|
|
668
|
+
var require_service_account_service = __commonJS({
|
|
669
|
+
"dist/auth/service-account-service.js"(exports2) {
|
|
670
|
+
"use strict";
|
|
671
|
+
var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
672
|
+
if (k2 === void 0) k2 = k;
|
|
673
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
674
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
675
|
+
desc = { enumerable: true, get: function() {
|
|
676
|
+
return m[k];
|
|
677
|
+
} };
|
|
678
|
+
}
|
|
679
|
+
Object.defineProperty(o, k2, desc);
|
|
680
|
+
}) : (function(o, m, k, k2) {
|
|
681
|
+
if (k2 === void 0) k2 = k;
|
|
682
|
+
o[k2] = m[k];
|
|
683
|
+
}));
|
|
684
|
+
var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
685
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
686
|
+
}) : function(o, v) {
|
|
687
|
+
o["default"] = v;
|
|
688
|
+
});
|
|
689
|
+
var __importStar2 = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
690
|
+
var ownKeys = function(o) {
|
|
691
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
692
|
+
var ar = [];
|
|
693
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
694
|
+
return ar;
|
|
695
|
+
};
|
|
696
|
+
return ownKeys(o);
|
|
697
|
+
};
|
|
698
|
+
return function(mod) {
|
|
699
|
+
if (mod && mod.__esModule) return mod;
|
|
700
|
+
var result = {};
|
|
701
|
+
if (mod != null) {
|
|
702
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding2(result, mod, k[i]);
|
|
255
703
|
}
|
|
256
|
-
|
|
257
|
-
|
|
704
|
+
__setModuleDefault2(result, mod);
|
|
705
|
+
return result;
|
|
706
|
+
};
|
|
707
|
+
})();
|
|
708
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
709
|
+
exports2.ServiceAccountService = void 0;
|
|
710
|
+
var fs2 = __importStar2(require("fs"));
|
|
711
|
+
var types_12 = require_types();
|
|
712
|
+
var noopLogger = {
|
|
713
|
+
info: () => {
|
|
714
|
+
},
|
|
715
|
+
warn: () => {
|
|
716
|
+
},
|
|
717
|
+
error: () => {
|
|
718
|
+
},
|
|
719
|
+
debug: () => {
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
var ServiceAccountService = class {
|
|
723
|
+
tokenPath;
|
|
724
|
+
tenantId;
|
|
725
|
+
tokenCache = null;
|
|
726
|
+
logger;
|
|
727
|
+
constructor(tokenPath, tenantId, logger) {
|
|
728
|
+
this.tokenPath = tokenPath;
|
|
729
|
+
this.tenantId = tenantId;
|
|
730
|
+
this.logger = logger || noopLogger;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Get the strategy type identifier
|
|
734
|
+
*/
|
|
735
|
+
getType() {
|
|
736
|
+
return types_12.AuthStrategyType.SERVICE_ACCOUNT;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Initialize the service account strategy
|
|
740
|
+
* Validates that the token file exists and is readable
|
|
741
|
+
*/
|
|
742
|
+
async initialize() {
|
|
743
|
+
this.logger.info(`Initializing ServiceAccountService with token path: ${this.tokenPath}`);
|
|
744
|
+
if (!fs2.existsSync(this.tokenPath)) {
|
|
745
|
+
throw new Error(`Service account token file not found: ${this.tokenPath}`);
|
|
258
746
|
}
|
|
259
|
-
|
|
260
|
-
|
|
747
|
+
await this.getToken();
|
|
748
|
+
this.logger.info("ServiceAccountService initialized successfully");
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Get a valid access token, reading from file if cache is expired
|
|
752
|
+
*/
|
|
753
|
+
async getToken() {
|
|
754
|
+
const now = Date.now();
|
|
755
|
+
const bufferMs = 5 * 60 * 1e3;
|
|
756
|
+
if (this.tokenCache && now < this.tokenCache.expiresAt - bufferMs) {
|
|
757
|
+
this.logger.debug("Using cached service account token");
|
|
758
|
+
return this.tokenCache.token;
|
|
261
759
|
}
|
|
760
|
+
const rawToken = this.readTokenFromFile();
|
|
761
|
+
this.validateAndCacheToken(rawToken);
|
|
762
|
+
return this.tokenCache.token;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Force refresh the token by clearing cache and re-reading from file
|
|
766
|
+
*/
|
|
767
|
+
async refreshToken() {
|
|
768
|
+
this.logger.info("Refreshing service account token...");
|
|
769
|
+
this.tokenCache = null;
|
|
770
|
+
await this.getToken();
|
|
771
|
+
this.logger.info("Service account token refreshed");
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Check if currently authenticated (token file exists and is valid)
|
|
775
|
+
*/
|
|
776
|
+
async isAuthenticated() {
|
|
777
|
+
try {
|
|
778
|
+
await this.getToken();
|
|
779
|
+
return true;
|
|
780
|
+
} catch {
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Get user information for the service account
|
|
786
|
+
* Returns synthetic user info since service accounts don't have traditional user profiles
|
|
787
|
+
*/
|
|
788
|
+
async getUserInfo() {
|
|
262
789
|
return {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
scope: this.config.scope ?? DEFAULT_SCOPE,
|
|
790
|
+
sub: "m2m-service-account",
|
|
791
|
+
name: "M2M Service Account",
|
|
792
|
+
...this.tenantId && { tenant_id: this.tenantId }
|
|
267
793
|
};
|
|
268
|
-
|
|
269
|
-
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Get the tenant ID associated with this service account
|
|
797
|
+
*/
|
|
798
|
+
getTenantId() {
|
|
799
|
+
return this.tenantId;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Read the token from the file system
|
|
803
|
+
*/
|
|
804
|
+
readTokenFromFile() {
|
|
805
|
+
return fs2.readFileSync(this.tokenPath, "utf8");
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Validate the token format and cache it with expiration
|
|
809
|
+
*/
|
|
810
|
+
validateAndCacheToken(rawToken) {
|
|
811
|
+
const token = rawToken.trim();
|
|
812
|
+
if (!token) {
|
|
813
|
+
throw new Error("Service account token is empty");
|
|
814
|
+
}
|
|
815
|
+
const parts = token.split(".");
|
|
816
|
+
if (parts.length !== 3) {
|
|
817
|
+
throw new Error(`Invalid JWT format: expected 3 parts, got ${parts.length}`);
|
|
818
|
+
}
|
|
819
|
+
const expiresAt = this.extractExpiration(token);
|
|
820
|
+
const now = Date.now();
|
|
821
|
+
const expiresIn = Math.floor((expiresAt - now) / 1e3);
|
|
822
|
+
if (expiresAt <= now) {
|
|
823
|
+
throw new Error("Service account token is expired");
|
|
824
|
+
}
|
|
825
|
+
this.logger.info(`Service account token loaded${this.tenantId ? ` for tenant ${this.tenantId}` : ""}: expires in ${expiresIn}s (${new Date(expiresAt).toISOString()})`);
|
|
826
|
+
this.tokenCache = {
|
|
827
|
+
token,
|
|
828
|
+
expiresAt
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Extract expiration time from JWT payload
|
|
833
|
+
*/
|
|
834
|
+
extractExpiration(token) {
|
|
835
|
+
const parts = token.split(".");
|
|
270
836
|
try {
|
|
271
|
-
|
|
837
|
+
const payload = parts[1];
|
|
838
|
+
const decoded = Buffer.from(payload, "base64url").toString("utf8");
|
|
839
|
+
const parsed = JSON.parse(decoded);
|
|
840
|
+
if (typeof parsed.exp === "number") {
|
|
841
|
+
return parsed.exp * 1e3;
|
|
842
|
+
}
|
|
843
|
+
this.logger.warn("JWT missing 'exp' field, using fallback expiration");
|
|
844
|
+
return Date.now() + 3e5;
|
|
845
|
+
} catch (error) {
|
|
846
|
+
this.logger.warn(`Failed to parse JWT expiration: ${error}, using fallback expiration`);
|
|
847
|
+
return Date.now() + 3e5;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
exports2.ServiceAccountService = ServiceAccountService;
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
// dist/auth/secrets/aws-secrets-provider.js
|
|
856
|
+
var require_aws_secrets_provider = __commonJS({
|
|
857
|
+
"dist/auth/secrets/aws-secrets-provider.js"(exports2) {
|
|
858
|
+
"use strict";
|
|
859
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
860
|
+
exports2.AWSSecretsProvider = void 0;
|
|
861
|
+
var noopLogger = {
|
|
862
|
+
info: () => {
|
|
863
|
+
},
|
|
864
|
+
warn: () => {
|
|
865
|
+
},
|
|
866
|
+
error: () => {
|
|
867
|
+
},
|
|
868
|
+
debug: () => {
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
var AWSSecretsProvider = class {
|
|
872
|
+
logger;
|
|
873
|
+
region;
|
|
874
|
+
constructor(logger) {
|
|
875
|
+
this.logger = logger || noopLogger;
|
|
876
|
+
this.region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Get the provider name for logging
|
|
880
|
+
*/
|
|
881
|
+
getName() {
|
|
882
|
+
return "AWS Secrets Manager";
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Check if running in AWS environment with credentials available
|
|
886
|
+
*/
|
|
887
|
+
async isAvailable() {
|
|
888
|
+
const hasRegion = !!(process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION);
|
|
889
|
+
const hasExecutionEnv = !!process.env.AWS_EXECUTION_ENV;
|
|
890
|
+
const hasCredentials = !!(process.env.AWS_ACCESS_KEY_ID || process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_WEB_IDENTITY_TOKEN_FILE);
|
|
891
|
+
const isAWSEnvironment = hasRegion && (hasExecutionEnv || hasCredentials);
|
|
892
|
+
if (isAWSEnvironment) {
|
|
893
|
+
this.logger.debug("AWS environment detected");
|
|
894
|
+
} else {
|
|
895
|
+
this.logger.debug("Not in AWS environment");
|
|
272
896
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
897
|
+
return isAWSEnvironment;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Load Auth0 M2M credentials from AWS Secrets Manager
|
|
901
|
+
*
|
|
902
|
+
* @param secretName - The name or ARN of the secret in Secrets Manager
|
|
903
|
+
* @returns M2M credentials or null if not found
|
|
904
|
+
*/
|
|
905
|
+
async loadAuth0M2MCredentials(secretName) {
|
|
906
|
+
this.logger.info(`Loading M2M credentials from AWS Secrets Manager: ${secretName}`);
|
|
907
|
+
try {
|
|
908
|
+
const { SecretsManagerClient, GetSecretValueCommand } = (
|
|
909
|
+
// @ts-expect-error - @aws-sdk/client-secrets-manager is an optional runtime dependency
|
|
910
|
+
await import("@aws-sdk/client-secrets-manager")
|
|
911
|
+
);
|
|
912
|
+
const client = new SecretsManagerClient({
|
|
913
|
+
region: this.region
|
|
914
|
+
});
|
|
915
|
+
const command = new GetSecretValueCommand({
|
|
916
|
+
SecretId: secretName
|
|
917
|
+
});
|
|
918
|
+
const response = await client.send(command);
|
|
919
|
+
if (!response.SecretString) {
|
|
920
|
+
this.logger.error("Secret value is empty or binary");
|
|
921
|
+
return null;
|
|
922
|
+
}
|
|
923
|
+
const secretValue = JSON.parse(response.SecretString);
|
|
924
|
+
if (!secretValue.client_id || !secretValue.client_secret || !secretValue.audience || !secretValue.domain) {
|
|
925
|
+
this.logger.error("Secret missing required fields (client_id, client_secret, audience, domain)");
|
|
926
|
+
return null;
|
|
927
|
+
}
|
|
928
|
+
this.logger.info("M2M credentials loaded from AWS Secrets Manager");
|
|
929
|
+
return {
|
|
930
|
+
client_id: secretValue.client_id,
|
|
931
|
+
client_secret: secretValue.client_secret,
|
|
932
|
+
audience: secretValue.audience,
|
|
933
|
+
domain: secretValue.domain
|
|
934
|
+
};
|
|
935
|
+
} catch (error) {
|
|
936
|
+
if (error instanceof Error) {
|
|
937
|
+
if (error.name === "ResourceNotFoundException") {
|
|
938
|
+
this.logger.warn(`Secret not found: ${secretName}`);
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
if (error.message.includes("Cannot find module")) {
|
|
942
|
+
this.logger.warn("AWS SDK not available - @aws-sdk/client-secrets-manager not installed");
|
|
943
|
+
return null;
|
|
278
944
|
}
|
|
279
|
-
|
|
280
|
-
|
|
945
|
+
this.logger.error("Failed to load secret from AWS", error);
|
|
946
|
+
}
|
|
947
|
+
return null;
|
|
281
948
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
exports2.AWSSecretsProvider = AWSSecretsProvider;
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// dist/auth/secrets/local-file-secrets-provider.js
|
|
956
|
+
var require_local_file_secrets_provider = __commonJS({
|
|
957
|
+
"dist/auth/secrets/local-file-secrets-provider.js"(exports2) {
|
|
958
|
+
"use strict";
|
|
959
|
+
var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
960
|
+
if (k2 === void 0) k2 = k;
|
|
961
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
962
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
963
|
+
desc = { enumerable: true, get: function() {
|
|
964
|
+
return m[k];
|
|
965
|
+
} };
|
|
966
|
+
}
|
|
967
|
+
Object.defineProperty(o, k2, desc);
|
|
968
|
+
}) : (function(o, m, k, k2) {
|
|
969
|
+
if (k2 === void 0) k2 = k;
|
|
970
|
+
o[k2] = m[k];
|
|
971
|
+
}));
|
|
972
|
+
var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
973
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
974
|
+
}) : function(o, v) {
|
|
975
|
+
o["default"] = v;
|
|
976
|
+
});
|
|
977
|
+
var __importStar2 = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
978
|
+
var ownKeys = function(o) {
|
|
979
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
980
|
+
var ar = [];
|
|
981
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
982
|
+
return ar;
|
|
983
|
+
};
|
|
984
|
+
return ownKeys(o);
|
|
985
|
+
};
|
|
986
|
+
return function(mod) {
|
|
987
|
+
if (mod && mod.__esModule) return mod;
|
|
988
|
+
var result = {};
|
|
989
|
+
if (mod != null) {
|
|
990
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding2(result, mod, k[i]);
|
|
991
|
+
}
|
|
992
|
+
__setModuleDefault2(result, mod);
|
|
993
|
+
return result;
|
|
994
|
+
};
|
|
995
|
+
})();
|
|
996
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
997
|
+
exports2.LocalFileSecretsProvider = void 0;
|
|
998
|
+
var fs2 = __importStar2(require("fs"));
|
|
999
|
+
var path2 = __importStar2(require("path"));
|
|
1000
|
+
var os2 = __importStar2(require("os"));
|
|
1001
|
+
var noopLogger = {
|
|
1002
|
+
info: () => {
|
|
1003
|
+
},
|
|
1004
|
+
warn: () => {
|
|
1005
|
+
},
|
|
1006
|
+
error: () => {
|
|
1007
|
+
},
|
|
1008
|
+
debug: () => {
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
var LocalFileSecretsProvider = class {
|
|
1012
|
+
logger;
|
|
1013
|
+
environment;
|
|
1014
|
+
secretFilePath;
|
|
1015
|
+
constructor(environment, logger) {
|
|
1016
|
+
this.logger = logger || noopLogger;
|
|
1017
|
+
this.environment = environment;
|
|
1018
|
+
this.secretFilePath = path2.join(os2.homedir(), ".dataflint", `m2m_secret.${environment}.json`);
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Get the provider name for logging
|
|
1022
|
+
*/
|
|
1023
|
+
getName() {
|
|
1024
|
+
return "Local File";
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Check if the local secret file exists
|
|
1028
|
+
*/
|
|
1029
|
+
async isAvailable() {
|
|
1030
|
+
const exists = fs2.existsSync(this.secretFilePath);
|
|
1031
|
+
if (exists) {
|
|
1032
|
+
this.logger.debug(`Local M2M secret file found: ${this.secretFilePath}`);
|
|
1033
|
+
} else {
|
|
1034
|
+
this.logger.debug(`Local M2M secret file not found: ${this.secretFilePath}`);
|
|
1035
|
+
}
|
|
1036
|
+
return exists;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Load Auth0 M2M credentials from local file
|
|
1040
|
+
*
|
|
1041
|
+
* @param _secretName - Ignored, uses environment-based file path
|
|
1042
|
+
* @returns M2M credentials or null if not found or invalid
|
|
1043
|
+
*/
|
|
1044
|
+
async loadAuth0M2MCredentials(_secretName) {
|
|
1045
|
+
this.logger.info(`Loading M2M credentials from local file: ${this.secretFilePath}`);
|
|
293
1046
|
try {
|
|
294
|
-
|
|
1047
|
+
if (!fs2.existsSync(this.secretFilePath)) {
|
|
1048
|
+
this.logger.debug("Local secret file does not exist");
|
|
1049
|
+
return null;
|
|
1050
|
+
}
|
|
1051
|
+
const stats = fs2.statSync(this.secretFilePath);
|
|
1052
|
+
const mode = stats.mode & 511;
|
|
1053
|
+
if (mode !== 384) {
|
|
1054
|
+
this.logger.warn(`Secret file has insecure permissions: ${mode.toString(8)}. Should be 600.`);
|
|
1055
|
+
}
|
|
1056
|
+
const content = fs2.readFileSync(this.secretFilePath, "utf8");
|
|
1057
|
+
const secretValue = JSON.parse(content);
|
|
1058
|
+
if (!secretValue.client_id || !secretValue.client_secret || !secretValue.audience || !secretValue.domain) {
|
|
1059
|
+
this.logger.error("Local secret file missing required fields (client_id, client_secret, audience, domain)");
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
this.logger.info("M2M credentials loaded from local file");
|
|
1063
|
+
return {
|
|
1064
|
+
client_id: secretValue.client_id,
|
|
1065
|
+
client_secret: secretValue.client_secret,
|
|
1066
|
+
audience: secretValue.audience,
|
|
1067
|
+
domain: secretValue.domain
|
|
1068
|
+
};
|
|
1069
|
+
} catch (error) {
|
|
1070
|
+
if (error instanceof SyntaxError) {
|
|
1071
|
+
this.logger.error("Failed to parse local secret file as JSON");
|
|
1072
|
+
} else {
|
|
1073
|
+
this.logger.error("Failed to load local secret file", error);
|
|
1074
|
+
}
|
|
1075
|
+
return null;
|
|
295
1076
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Get the path to the secret file (for diagnostics)
|
|
1080
|
+
*/
|
|
1081
|
+
getSecretFilePath() {
|
|
1082
|
+
return this.secretFilePath;
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
exports2.LocalFileSecretsProvider = LocalFileSecretsProvider;
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
|
|
1089
|
+
// dist/auth/secrets/secrets-provider.js
|
|
1090
|
+
var require_secrets_provider = __commonJS({
|
|
1091
|
+
"dist/auth/secrets/secrets-provider.js"(exports2) {
|
|
1092
|
+
"use strict";
|
|
1093
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1094
|
+
exports2.SecretsProvider = void 0;
|
|
1095
|
+
var aws_secrets_provider_1 = require_aws_secrets_provider();
|
|
1096
|
+
var local_file_secrets_provider_1 = require_local_file_secrets_provider();
|
|
1097
|
+
var noopLogger = {
|
|
1098
|
+
info: () => {
|
|
1099
|
+
},
|
|
1100
|
+
warn: () => {
|
|
1101
|
+
},
|
|
1102
|
+
error: () => {
|
|
1103
|
+
},
|
|
1104
|
+
debug: () => {
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
var SecretsProvider = class {
|
|
1108
|
+
logger;
|
|
1109
|
+
providers;
|
|
1110
|
+
environment;
|
|
1111
|
+
constructor(environment, logger) {
|
|
1112
|
+
this.logger = logger || noopLogger;
|
|
1113
|
+
this.environment = environment;
|
|
1114
|
+
this.providers = [
|
|
1115
|
+
new aws_secrets_provider_1.AWSSecretsProvider(logger),
|
|
1116
|
+
new local_file_secrets_provider_1.LocalFileSecretsProvider(environment, logger)
|
|
1117
|
+
];
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Get the provider name for logging
|
|
1121
|
+
*/
|
|
1122
|
+
getName() {
|
|
1123
|
+
return "Composite Secrets Provider";
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Check if any provider is available
|
|
1127
|
+
*/
|
|
1128
|
+
async isAvailable() {
|
|
1129
|
+
for (const provider of this.providers) {
|
|
1130
|
+
if (await provider.isAvailable()) {
|
|
1131
|
+
this.logger.debug(`Secrets provider available: ${provider.getName()}`);
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
this.logger.debug("No secrets providers available");
|
|
1136
|
+
return false;
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Load Auth0 M2M credentials from the first available provider
|
|
1140
|
+
*
|
|
1141
|
+
* @param secretName - The name of the secret (used for AWS, ignored for local file)
|
|
1142
|
+
* @returns M2M credentials or null if not found in any provider
|
|
1143
|
+
*/
|
|
1144
|
+
async loadAuth0M2MCredentials(secretName) {
|
|
1145
|
+
this.logger.info("Attempting to load M2M credentials...");
|
|
1146
|
+
for (const provider of this.providers) {
|
|
1147
|
+
const providerName = provider.getName();
|
|
1148
|
+
if (!await provider.isAvailable()) {
|
|
1149
|
+
this.logger.debug(`Provider not available: ${providerName}`);
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
this.logger.info(`Trying provider: ${providerName}`);
|
|
1153
|
+
const credentials = await provider.loadAuth0M2MCredentials(secretName);
|
|
1154
|
+
if (credentials) {
|
|
1155
|
+
this.logger.info(`M2M credentials loaded from: ${providerName}`);
|
|
1156
|
+
return credentials;
|
|
1157
|
+
}
|
|
1158
|
+
this.logger.debug(`No credentials found in provider: ${providerName}`);
|
|
303
1159
|
}
|
|
1160
|
+
this.logger.info("No M2M credentials found in any provider");
|
|
1161
|
+
return null;
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Get the default secret name for M2M credentials based on environment
|
|
1165
|
+
*
|
|
1166
|
+
* @param environment - The environment (prod, staging, local)
|
|
1167
|
+
* @returns The default secret name
|
|
1168
|
+
*/
|
|
1169
|
+
static getDefaultSecretName(environment) {
|
|
1170
|
+
return `auth0_m2m_databricks_loader_${environment}`;
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
exports2.SecretsProvider = SecretsProvider;
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
|
|
1177
|
+
// dist/auth/secrets/index.js
|
|
1178
|
+
var require_secrets = __commonJS({
|
|
1179
|
+
"dist/auth/secrets/index.js"(exports2) {
|
|
1180
|
+
"use strict";
|
|
1181
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1182
|
+
exports2.SecretsProvider = exports2.LocalFileSecretsProvider = exports2.AWSSecretsProvider = void 0;
|
|
1183
|
+
var aws_secrets_provider_1 = require_aws_secrets_provider();
|
|
1184
|
+
Object.defineProperty(exports2, "AWSSecretsProvider", { enumerable: true, get: function() {
|
|
1185
|
+
return aws_secrets_provider_1.AWSSecretsProvider;
|
|
1186
|
+
} });
|
|
1187
|
+
var local_file_secrets_provider_1 = require_local_file_secrets_provider();
|
|
1188
|
+
Object.defineProperty(exports2, "LocalFileSecretsProvider", { enumerable: true, get: function() {
|
|
1189
|
+
return local_file_secrets_provider_1.LocalFileSecretsProvider;
|
|
1190
|
+
} });
|
|
1191
|
+
var secrets_provider_1 = require_secrets_provider();
|
|
1192
|
+
Object.defineProperty(exports2, "SecretsProvider", { enumerable: true, get: function() {
|
|
1193
|
+
return secrets_provider_1.SecretsProvider;
|
|
1194
|
+
} });
|
|
1195
|
+
}
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1198
|
+
// dist/auth/auth-strategy-factory.js
|
|
1199
|
+
var require_auth_strategy_factory = __commonJS({
|
|
1200
|
+
"dist/auth/auth-strategy-factory.js"(exports2) {
|
|
1201
|
+
"use strict";
|
|
1202
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1203
|
+
exports2.AuthStrategyFactory = void 0;
|
|
1204
|
+
var types_12 = require_types();
|
|
1205
|
+
var service_account_service_1 = require_service_account_service();
|
|
1206
|
+
var auth0_m2m_service_1 = require_auth0_m2m_service();
|
|
1207
|
+
var secrets_1 = require_secrets();
|
|
1208
|
+
var noopLogger = {
|
|
1209
|
+
info: () => {
|
|
1210
|
+
},
|
|
1211
|
+
warn: () => {
|
|
1212
|
+
},
|
|
1213
|
+
error: () => {
|
|
1214
|
+
},
|
|
1215
|
+
debug: () => {
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
var AuthStrategyFactory = class {
|
|
1219
|
+
configProvider;
|
|
1220
|
+
logger;
|
|
1221
|
+
constructor(configProvider, logger) {
|
|
1222
|
+
this.configProvider = configProvider;
|
|
1223
|
+
this.logger = logger || noopLogger;
|
|
1224
|
+
}
|
|
1225
|
+
async createStrategy() {
|
|
1226
|
+
const m2mMode = this.configProvider.getM2MMode();
|
|
1227
|
+
switch (m2mMode.type) {
|
|
1228
|
+
case types_12.M2MType.SERVICE_ACCOUNT:
|
|
1229
|
+
return this.buildServiceAccountStrategy(m2mMode);
|
|
1230
|
+
case types_12.M2MType.AUTH0_M2M:
|
|
1231
|
+
return await this.buildAuth0M2MStrategy(m2mMode);
|
|
1232
|
+
default:
|
|
1233
|
+
this.logger.info("Using interactive OAuth flow");
|
|
1234
|
+
return {
|
|
1235
|
+
strategy: null,
|
|
1236
|
+
strategyType: types_12.AuthStrategyType.AUTH0_USER
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
buildServiceAccountStrategy(mode) {
|
|
1241
|
+
this.logger.info(`Service Account mode: ${mode.tokenPath}`);
|
|
1242
|
+
return {
|
|
1243
|
+
strategy: new service_account_service_1.ServiceAccountService(mode.tokenPath, mode.tenantId, this.logger),
|
|
1244
|
+
strategyType: types_12.AuthStrategyType.SERVICE_ACCOUNT
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
async buildAuth0M2MStrategy(mode) {
|
|
1248
|
+
const secretsProvider = new secrets_1.SecretsProvider(this.configProvider.getEnvironment(), this.logger);
|
|
1249
|
+
if (!await secretsProvider.isAvailable()) {
|
|
1250
|
+
throw new Error(`Auth0 M2M mode requires a secrets provider. M2M_AUTH0_SECRET_NAME is set to "${mode.secretName}" but no secrets provider is available. Ensure AWS credentials are configured or use Service Account mode instead.`);
|
|
1251
|
+
}
|
|
1252
|
+
const credentials = await secretsProvider.loadAuth0M2MCredentials(mode.secretName);
|
|
1253
|
+
if (!credentials) {
|
|
1254
|
+
throw new Error(`Auth0 M2M credentials not found: "${mode.secretName}". Ensure the secret exists and contains valid Auth0 M2M credentials.`);
|
|
1255
|
+
}
|
|
1256
|
+
this.logger.info(`Auth0 M2M mode: ${mode.secretName}`);
|
|
1257
|
+
return {
|
|
1258
|
+
strategy: new auth0_m2m_service_1.Auth0M2MService(credentials, mode.tenantId, this.logger),
|
|
1259
|
+
strategyType: types_12.AuthStrategyType.AUTH0_M2M
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
async isM2MAvailable() {
|
|
1263
|
+
const mode = this.configProvider.getM2MMode();
|
|
1264
|
+
if (mode.type === types_12.M2MType.SERVICE_ACCOUNT) {
|
|
1265
|
+
return true;
|
|
1266
|
+
}
|
|
1267
|
+
if (mode.type === types_12.M2MType.AUTH0_M2M) {
|
|
1268
|
+
const secretsProvider = new secrets_1.SecretsProvider(this.configProvider.getEnvironment(), this.logger);
|
|
1269
|
+
return secretsProvider.isAvailable();
|
|
1270
|
+
}
|
|
1271
|
+
return false;
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
exports2.AuthStrategyFactory = AuthStrategyFactory;
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
// dist/auth/index.js
|
|
1279
|
+
var require_auth = __commonJS({
|
|
1280
|
+
"dist/auth/index.js"(exports2) {
|
|
1281
|
+
"use strict";
|
|
1282
|
+
var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
1283
|
+
if (k2 === void 0) k2 = k;
|
|
1284
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1285
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1286
|
+
desc = { enumerable: true, get: function() {
|
|
1287
|
+
return m[k];
|
|
1288
|
+
} };
|
|
1289
|
+
}
|
|
1290
|
+
Object.defineProperty(o, k2, desc);
|
|
1291
|
+
}) : (function(o, m, k, k2) {
|
|
1292
|
+
if (k2 === void 0) k2 = k;
|
|
1293
|
+
o[k2] = m[k];
|
|
1294
|
+
}));
|
|
1295
|
+
var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
1296
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1297
|
+
}) : function(o, v) {
|
|
1298
|
+
o["default"] = v;
|
|
1299
|
+
});
|
|
1300
|
+
var __importStar2 = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
1301
|
+
var ownKeys = function(o) {
|
|
1302
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
1303
|
+
var ar = [];
|
|
1304
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
1305
|
+
return ar;
|
|
1306
|
+
};
|
|
1307
|
+
return ownKeys(o);
|
|
1308
|
+
};
|
|
1309
|
+
return function(mod) {
|
|
1310
|
+
if (mod && mod.__esModule) return mod;
|
|
1311
|
+
var result = {};
|
|
1312
|
+
if (mod != null) {
|
|
1313
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding2(result, mod, k[i]);
|
|
1314
|
+
}
|
|
1315
|
+
__setModuleDefault2(result, mod);
|
|
1316
|
+
return result;
|
|
1317
|
+
};
|
|
1318
|
+
})();
|
|
1319
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1320
|
+
exports2.NetworkError = exports2.ConfigError = exports2.AuthError = exports2.DataFlintError = exports2.ErrorCode = exports2.SecretsProvider = exports2.LocalFileSecretsProvider = exports2.AWSSecretsProvider = exports2.AuthStrategyFactory = exports2.ServiceAccountService = exports2.Auth0M2MService = exports2.Auth0Service = exports2.M2MType = exports2.AuthStrategyType = exports2.customerAuthConfigs = void 0;
|
|
1321
|
+
exports2.getCustomerAuthConfig = getCustomerAuthConfig;
|
|
1322
|
+
var crypto2 = __importStar2(require("node:crypto"));
|
|
1323
|
+
var customer_auth_configs_1 = require_customer_auth_configs();
|
|
1324
|
+
Object.defineProperty(exports2, "customerAuthConfigs", { enumerable: true, get: function() {
|
|
1325
|
+
return customer_auth_configs_1.customerAuthConfigs;
|
|
1326
|
+
} });
|
|
1327
|
+
function getCustomerAuthConfig(customerDomain) {
|
|
1328
|
+
var _a;
|
|
1329
|
+
const customerHash = crypto2.createHash("sha256").update(customerDomain).digest("hex");
|
|
1330
|
+
const customerConfig = customer_auth_configs_1.customerAuthConfigs[customerHash];
|
|
1331
|
+
if (!customerConfig) {
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
return {
|
|
1335
|
+
// Use custom Auth0 domain if domainProducer is defined, otherwise use default
|
|
1336
|
+
domain: ((_a = customerConfig.domainProducer) == null ? void 0 : _a.call(customerConfig, customerDomain)) || "https://dataflint.us.auth0.com/",
|
|
1337
|
+
// Customer-specific Auth0 client ID
|
|
1338
|
+
clientId: customerConfig.clientId,
|
|
1339
|
+
// Customer-specific API audience
|
|
1340
|
+
audience: `https://api.${customerDomain}.dataflint.io`,
|
|
1341
|
+
// Customer-specific server URL
|
|
1342
|
+
serverUrl: `https://api.${customerDomain}.dataflint.io`
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
var types_12 = require_types();
|
|
1346
|
+
Object.defineProperty(exports2, "AuthStrategyType", { enumerable: true, get: function() {
|
|
1347
|
+
return types_12.AuthStrategyType;
|
|
1348
|
+
} });
|
|
1349
|
+
Object.defineProperty(exports2, "M2MType", { enumerable: true, get: function() {
|
|
1350
|
+
return types_12.M2MType;
|
|
1351
|
+
} });
|
|
1352
|
+
var auth0_service_1 = require_auth0_service();
|
|
1353
|
+
Object.defineProperty(exports2, "Auth0Service", { enumerable: true, get: function() {
|
|
1354
|
+
return auth0_service_1.Auth0Service;
|
|
1355
|
+
} });
|
|
1356
|
+
var auth0_m2m_service_1 = require_auth0_m2m_service();
|
|
1357
|
+
Object.defineProperty(exports2, "Auth0M2MService", { enumerable: true, get: function() {
|
|
1358
|
+
return auth0_m2m_service_1.Auth0M2MService;
|
|
1359
|
+
} });
|
|
1360
|
+
var service_account_service_1 = require_service_account_service();
|
|
1361
|
+
Object.defineProperty(exports2, "ServiceAccountService", { enumerable: true, get: function() {
|
|
1362
|
+
return service_account_service_1.ServiceAccountService;
|
|
1363
|
+
} });
|
|
1364
|
+
var auth_strategy_factory_1 = require_auth_strategy_factory();
|
|
1365
|
+
Object.defineProperty(exports2, "AuthStrategyFactory", { enumerable: true, get: function() {
|
|
1366
|
+
return auth_strategy_factory_1.AuthStrategyFactory;
|
|
1367
|
+
} });
|
|
1368
|
+
var secrets_1 = require_secrets();
|
|
1369
|
+
Object.defineProperty(exports2, "AWSSecretsProvider", { enumerable: true, get: function() {
|
|
1370
|
+
return secrets_1.AWSSecretsProvider;
|
|
1371
|
+
} });
|
|
1372
|
+
Object.defineProperty(exports2, "LocalFileSecretsProvider", { enumerable: true, get: function() {
|
|
1373
|
+
return secrets_1.LocalFileSecretsProvider;
|
|
1374
|
+
} });
|
|
1375
|
+
Object.defineProperty(exports2, "SecretsProvider", { enumerable: true, get: function() {
|
|
1376
|
+
return secrets_1.SecretsProvider;
|
|
1377
|
+
} });
|
|
1378
|
+
var errors_1 = require_errors();
|
|
1379
|
+
Object.defineProperty(exports2, "ErrorCode", { enumerable: true, get: function() {
|
|
1380
|
+
return errors_1.ErrorCode;
|
|
1381
|
+
} });
|
|
1382
|
+
Object.defineProperty(exports2, "DataFlintError", { enumerable: true, get: function() {
|
|
1383
|
+
return errors_1.DataFlintError;
|
|
1384
|
+
} });
|
|
1385
|
+
Object.defineProperty(exports2, "AuthError", { enumerable: true, get: function() {
|
|
1386
|
+
return errors_1.AuthError;
|
|
1387
|
+
} });
|
|
1388
|
+
Object.defineProperty(exports2, "ConfigError", { enumerable: true, get: function() {
|
|
1389
|
+
return errors_1.ConfigError;
|
|
1390
|
+
} });
|
|
1391
|
+
Object.defineProperty(exports2, "NetworkError", { enumerable: true, get: function() {
|
|
1392
|
+
return errors_1.NetworkError;
|
|
1393
|
+
} });
|
|
1394
|
+
}
|
|
1395
|
+
});
|
|
1396
|
+
|
|
1397
|
+
// dist/types.js
|
|
1398
|
+
var require_types2 = __commonJS({
|
|
1399
|
+
"dist/types.js"(exports2) {
|
|
1400
|
+
"use strict";
|
|
1401
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1402
|
+
exports2.M2MType = exports2.AuthStrategyType = void 0;
|
|
1403
|
+
var index_12 = require_auth();
|
|
1404
|
+
Object.defineProperty(exports2, "AuthStrategyType", { enumerable: true, get: function() {
|
|
1405
|
+
return index_12.AuthStrategyType;
|
|
1406
|
+
} });
|
|
1407
|
+
Object.defineProperty(exports2, "M2MType", { enumerable: true, get: function() {
|
|
1408
|
+
return index_12.M2MType;
|
|
1409
|
+
} });
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
// dist/logger.js
|
|
1414
|
+
var require_logger = __commonJS({
|
|
1415
|
+
"dist/logger.js"(exports2) {
|
|
1416
|
+
"use strict";
|
|
1417
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1418
|
+
exports2.Logger = void 0;
|
|
1419
|
+
var LOGGER_KEY = "__dataflint_mcp_logger__";
|
|
1420
|
+
var Logger = class {
|
|
1421
|
+
static setInstance(logger) {
|
|
1422
|
+
globalThis[LOGGER_KEY] = logger;
|
|
1423
|
+
}
|
|
1424
|
+
static getInstance() {
|
|
1425
|
+
const instance = globalThis[LOGGER_KEY];
|
|
1426
|
+
if (!instance) {
|
|
1427
|
+
throw new Error("Logger not initialized. Call Logger.setInstance() first.");
|
|
1428
|
+
}
|
|
1429
|
+
return instance;
|
|
1430
|
+
}
|
|
1431
|
+
static clear() {
|
|
1432
|
+
globalThis[LOGGER_KEY] = void 0;
|
|
1433
|
+
}
|
|
1434
|
+
};
|
|
1435
|
+
exports2.Logger = Logger;
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
// dist/standalone/config.js
|
|
1440
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
1441
|
+
if (k2 === void 0) k2 = k;
|
|
1442
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1443
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1444
|
+
desc = { enumerable: true, get: function() {
|
|
1445
|
+
return m[k];
|
|
1446
|
+
} };
|
|
1447
|
+
}
|
|
1448
|
+
Object.defineProperty(o, k2, desc);
|
|
1449
|
+
}) : (function(o, m, k, k2) {
|
|
1450
|
+
if (k2 === void 0) k2 = k;
|
|
1451
|
+
o[k2] = m[k];
|
|
1452
|
+
}));
|
|
1453
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
1454
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1455
|
+
}) : function(o, v) {
|
|
1456
|
+
o["default"] = v;
|
|
1457
|
+
});
|
|
1458
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
1459
|
+
var ownKeys = function(o) {
|
|
1460
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
1461
|
+
var ar = [];
|
|
1462
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
1463
|
+
return ar;
|
|
1464
|
+
};
|
|
1465
|
+
return ownKeys(o);
|
|
1466
|
+
};
|
|
1467
|
+
return function(mod) {
|
|
1468
|
+
if (mod && mod.__esModule) return mod;
|
|
1469
|
+
var result = {};
|
|
1470
|
+
if (mod != null) {
|
|
1471
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
1472
|
+
}
|
|
1473
|
+
__setModuleDefault(result, mod);
|
|
1474
|
+
return result;
|
|
1475
|
+
};
|
|
1476
|
+
})();
|
|
1477
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1478
|
+
exports.StandaloneConfigService = void 0;
|
|
1479
|
+
var fs = __importStar(require("node:fs"));
|
|
1480
|
+
var fsPromises = __importStar(require("node:fs/promises"));
|
|
1481
|
+
var path = __importStar(require("node:path"));
|
|
1482
|
+
var os = __importStar(require("node:os"));
|
|
1483
|
+
var crypto = __importStar(require("node:crypto"));
|
|
1484
|
+
var zod_1 = require("zod");
|
|
1485
|
+
var types_1 = require_types2();
|
|
1486
|
+
var index_1 = require_auth();
|
|
1487
|
+
var logger_1 = require_logger();
|
|
1488
|
+
var DEFAULT_CLIENT_ID_FOR_HASH = "default";
|
|
1489
|
+
var HASH_PREFIX_LENGTH = 8;
|
|
1490
|
+
var DEFAULT_ADMIN_COMPANY_DOMAIN = "none";
|
|
1491
|
+
var DEFAULT_SERVER_URL = "https://api.dataflint.io";
|
|
1492
|
+
var DEFAULT_AUTH_DOMAIN = "https://dataflint.us.auth0.com/";
|
|
1493
|
+
var DEFAULT_AUDIENCE = "https://api.dataflint.io";
|
|
1494
|
+
var DEFAULT_SCOPE = "openid profile email offline_access";
|
|
1495
|
+
var DEFAULT_PUBLIC_CLIENT_ID = "1NdbhkYoLyqQWtevBNal1BozB9pSZe3g";
|
|
1496
|
+
var CREDENTIALS_DIR_MODE = 448;
|
|
1497
|
+
var CREDENTIALS_FILE_MODE = 384;
|
|
1498
|
+
var StandaloneConfigSchema = zod_1.z.object({
|
|
1499
|
+
serverUrl: zod_1.z.string().url().optional(),
|
|
1500
|
+
authDomain: zod_1.z.string().optional(),
|
|
1501
|
+
clientId: zod_1.z.string().optional(),
|
|
1502
|
+
audience: zod_1.z.string().optional(),
|
|
1503
|
+
scope: zod_1.z.string().optional(),
|
|
1504
|
+
credentialsPath: zod_1.z.string().optional(),
|
|
1505
|
+
adminCompanyDomain: zod_1.z.string().optional(),
|
|
1506
|
+
customerDomain: zod_1.z.string().optional(),
|
|
1507
|
+
m2mTokenPath: zod_1.z.string().optional(),
|
|
1508
|
+
m2mSecretName: zod_1.z.string().optional(),
|
|
1509
|
+
tenantId: zod_1.z.string().optional()
|
|
1510
|
+
}).strict();
|
|
1511
|
+
var StandaloneConfigService = class {
|
|
1512
|
+
config;
|
|
1513
|
+
credentialsPath;
|
|
1514
|
+
m2mMode;
|
|
1515
|
+
constructor(config = {}) {
|
|
1516
|
+
this.config = this.mergeWithDefaults(config);
|
|
1517
|
+
this.m2mMode = this.detectM2MMode();
|
|
1518
|
+
this.validateM2MConfig();
|
|
1519
|
+
this.credentialsPath = config.credentialsPath || this.defaultCredentialsPath();
|
|
1520
|
+
this.ensureDataflintDirectory();
|
|
1521
|
+
}
|
|
1522
|
+
defaultCredentialsPath() {
|
|
1523
|
+
const hash = crypto.createHash("sha256").update(this.config.clientId || DEFAULT_CLIENT_ID_FOR_HASH).digest("hex").substring(0, HASH_PREFIX_LENGTH);
|
|
1524
|
+
return path.join(os.homedir(), ".dataflint", `credentials-${hash}.json`);
|
|
1525
|
+
}
|
|
1526
|
+
ensureDataflintDirectory() {
|
|
1527
|
+
const dir = path.dirname(this.credentialsPath);
|
|
1528
|
+
if (!fs.existsSync(dir)) {
|
|
1529
|
+
fs.mkdirSync(dir, { recursive: true, mode: CREDENTIALS_DIR_MODE });
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
detectM2MMode() {
|
|
1533
|
+
const tokenPath = this.config.m2mTokenPath;
|
|
1534
|
+
const secretName = this.config.m2mSecretName;
|
|
1535
|
+
const tenantId = this.config.tenantId;
|
|
1536
|
+
const logger = logger_1.Logger.getInstance();
|
|
1537
|
+
if (tokenPath) {
|
|
1538
|
+
logger.info("M2M mode: Service Account");
|
|
1539
|
+
return { type: types_1.M2MType.SERVICE_ACCOUNT, tokenPath, tenantId };
|
|
1540
|
+
}
|
|
1541
|
+
if (secretName) {
|
|
1542
|
+
logger.info("M2M mode: Auth0 M2M");
|
|
1543
|
+
return { type: types_1.M2MType.AUTH0_M2M, secretName, tenantId };
|
|
1544
|
+
}
|
|
1545
|
+
return { type: types_1.M2MType.NONE };
|
|
1546
|
+
}
|
|
1547
|
+
validateM2MConfig() {
|
|
1548
|
+
if (this.m2mMode.type !== types_1.M2MType.NONE && !this.config.serverUrl) {
|
|
1549
|
+
throw new Error("DATAFLINT_SERVER_URL is required in M2M mode");
|
|
304
1550
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
1551
|
+
}
|
|
1552
|
+
loadFileConfig() {
|
|
1553
|
+
const configFilePath = path.join(os.homedir(), ".dataflint", "config.json");
|
|
1554
|
+
if (!fs.existsSync(configFilePath)) {
|
|
1555
|
+
return {};
|
|
308
1556
|
}
|
|
309
|
-
|
|
310
|
-
|
|
1557
|
+
const logger = logger_1.Logger.getInstance();
|
|
1558
|
+
try {
|
|
1559
|
+
const rawContent = JSON.parse(fs.readFileSync(configFilePath, "utf8"));
|
|
1560
|
+
const result = StandaloneConfigSchema.safeParse(rawContent);
|
|
1561
|
+
if (!result.success) {
|
|
1562
|
+
logger.warn(`Invalid config file format at ${configFilePath}: ${result.error.issues.map((i) => i.message).join(", ")}`);
|
|
1563
|
+
return {};
|
|
1564
|
+
}
|
|
1565
|
+
return result.data;
|
|
1566
|
+
} catch (error) {
|
|
1567
|
+
logger.warn(`Failed to parse config file at ${configFilePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1568
|
+
return {};
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
mergeWithDefaults(config) {
|
|
1572
|
+
const envConfig = {
|
|
1573
|
+
serverUrl: process.env.DATAFLINT_SERVER_URL,
|
|
1574
|
+
authDomain: process.env.DATAFLINT_AUTH_DOMAIN,
|
|
1575
|
+
clientId: process.env.DATAFLINT_CLIENT_ID,
|
|
1576
|
+
audience: process.env.DATAFLINT_AUDIENCE,
|
|
1577
|
+
scope: process.env.DATAFLINT_SCOPE,
|
|
1578
|
+
adminCompanyDomain: process.env.DATAFLINT_ADMIN_COMPANY_DOMAIN,
|
|
1579
|
+
customerDomain: process.env.DATAFLINT_CUSTOMER_DOMAIN,
|
|
1580
|
+
m2mTokenPath: process.env.M2M_SA_TOKEN_PATH,
|
|
1581
|
+
m2mSecretName: process.env.M2M_AUTH0_SECRET_NAME,
|
|
1582
|
+
tenantId: process.env.TENANT_ID
|
|
1583
|
+
};
|
|
1584
|
+
const fileConfig = this.loadFileConfig();
|
|
1585
|
+
const logger = logger_1.Logger.getInstance();
|
|
1586
|
+
const customerDomain = config.customerDomain || envConfig.customerDomain || fileConfig.customerDomain;
|
|
1587
|
+
if (customerDomain) {
|
|
1588
|
+
logger.info(`Customer domain detected: ${customerDomain}`);
|
|
1589
|
+
const customerConfig = (0, index_1.getCustomerAuthConfig)(customerDomain);
|
|
1590
|
+
if (!customerConfig) {
|
|
1591
|
+
logger.error(`Unknown customer domain: ${customerDomain}`);
|
|
1592
|
+
throw new Error(`Unknown customer domain: "${customerDomain}". This customer is not registered in the system. Please check the domain name or contact support.`);
|
|
1593
|
+
}
|
|
1594
|
+
logger.info(`Using customer-specific configuration:`);
|
|
1595
|
+
logger.info(`Server URL: ${customerConfig.serverUrl}`);
|
|
1596
|
+
logger.info(`Auth0 Domain: ${customerConfig.domain}`);
|
|
1597
|
+
logger.info(`Client ID: ${customerConfig.clientId.substring(0, 8)}...`);
|
|
1598
|
+
return {
|
|
1599
|
+
serverUrl: customerConfig.serverUrl,
|
|
1600
|
+
authDomain: customerConfig.domain,
|
|
1601
|
+
clientId: customerConfig.clientId,
|
|
1602
|
+
audience: customerConfig.audience,
|
|
1603
|
+
scope: DEFAULT_SCOPE,
|
|
1604
|
+
// Credentials path only configurable via CLI argument for security
|
|
1605
|
+
credentialsPath: config.credentialsPath,
|
|
1606
|
+
adminCompanyDomain: config.adminCompanyDomain || envConfig.adminCompanyDomain || fileConfig.adminCompanyDomain || DEFAULT_ADMIN_COMPANY_DOMAIN,
|
|
1607
|
+
customerDomain,
|
|
1608
|
+
m2mTokenPath: config.m2mTokenPath || envConfig.m2mTokenPath || fileConfig.m2mTokenPath,
|
|
1609
|
+
m2mSecretName: config.m2mSecretName || envConfig.m2mSecretName || fileConfig.m2mSecretName,
|
|
1610
|
+
tenantId: config.tenantId || envConfig.tenantId || fileConfig.tenantId
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
logger.info(`No customer domain - using default/explicit configuration`);
|
|
1614
|
+
return {
|
|
1615
|
+
serverUrl: config.serverUrl || envConfig.serverUrl || fileConfig.serverUrl || DEFAULT_SERVER_URL,
|
|
1616
|
+
authDomain: config.authDomain || envConfig.authDomain || fileConfig.authDomain || DEFAULT_AUTH_DOMAIN,
|
|
1617
|
+
clientId: config.clientId || envConfig.clientId || fileConfig.clientId || DEFAULT_PUBLIC_CLIENT_ID,
|
|
1618
|
+
audience: config.audience || envConfig.audience || fileConfig.audience || DEFAULT_AUDIENCE,
|
|
1619
|
+
scope: config.scope || envConfig.scope || fileConfig.scope || DEFAULT_SCOPE,
|
|
1620
|
+
adminCompanyDomain: config.adminCompanyDomain || envConfig.adminCompanyDomain || fileConfig.adminCompanyDomain || DEFAULT_ADMIN_COMPANY_DOMAIN,
|
|
1621
|
+
// Credentials path only configurable via CLI argument for security
|
|
1622
|
+
credentialsPath: config.credentialsPath,
|
|
1623
|
+
customerDomain: void 0,
|
|
1624
|
+
m2mTokenPath: config.m2mTokenPath || envConfig.m2mTokenPath || fileConfig.m2mTokenPath,
|
|
1625
|
+
m2mSecretName: config.m2mSecretName || envConfig.m2mSecretName || fileConfig.m2mSecretName,
|
|
1626
|
+
tenantId: config.tenantId || envConfig.tenantId || fileConfig.tenantId
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
// IConfigService interface implementation
|
|
1630
|
+
getServerUrl() {
|
|
1631
|
+
if (!this.config.serverUrl) {
|
|
1632
|
+
throw new Error("Server URL not configured. Set DATAFLINT_SERVER_URL environment variable or configure in ~/.dataflint/config.json");
|
|
1633
|
+
}
|
|
1634
|
+
return this.config.serverUrl;
|
|
1635
|
+
}
|
|
1636
|
+
getEnvironment() {
|
|
1637
|
+
return "prod";
|
|
1638
|
+
}
|
|
1639
|
+
getCustomerDomain() {
|
|
1640
|
+
return this.config.customerDomain ?? null;
|
|
1641
|
+
}
|
|
1642
|
+
getAdminCompanyDomain() {
|
|
1643
|
+
return this.config.adminCompanyDomain ?? DEFAULT_ADMIN_COMPANY_DOMAIN;
|
|
1644
|
+
}
|
|
1645
|
+
getAuthConfig() {
|
|
1646
|
+
if (!this.config.authDomain) {
|
|
1647
|
+
throw new Error("Auth domain not configured. Set DATAFLINT_AUTH_DOMAIN environment variable or configure in ~/.dataflint/config.json");
|
|
1648
|
+
}
|
|
1649
|
+
if (!this.config.clientId) {
|
|
1650
|
+
throw new Error("Client ID not configured. Set DATAFLINT_CLIENT_ID environment variable or configure in ~/.dataflint/config.json");
|
|
1651
|
+
}
|
|
1652
|
+
if (!this.config.audience) {
|
|
1653
|
+
throw new Error("Audience not configured. Set DATAFLINT_AUDIENCE environment variable or configure in ~/.dataflint/config.json");
|
|
1654
|
+
}
|
|
1655
|
+
return {
|
|
1656
|
+
domain: this.config.authDomain,
|
|
1657
|
+
clientId: this.config.clientId,
|
|
1658
|
+
audience: this.config.audience,
|
|
1659
|
+
scope: this.config.scope ?? DEFAULT_SCOPE
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
async getAuthSecret() {
|
|
1663
|
+
try {
|
|
1664
|
+
return await fsPromises.readFile(this.credentialsPath, "utf8");
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
const nodeError = error;
|
|
1667
|
+
if (nodeError.code === "ENOENT") {
|
|
1668
|
+
return void 0;
|
|
1669
|
+
}
|
|
1670
|
+
logger_1.Logger.getInstance().warn(`Failed to read credentials from ${this.credentialsPath}: ${nodeError.message}`);
|
|
1671
|
+
return void 0;
|
|
311
1672
|
}
|
|
312
|
-
|
|
313
|
-
|
|
1673
|
+
}
|
|
1674
|
+
async setAuthSecret(value) {
|
|
1675
|
+
this.ensureDataflintDirectory();
|
|
1676
|
+
await fsPromises.writeFile(this.credentialsPath, value, {
|
|
1677
|
+
mode: CREDENTIALS_FILE_MODE,
|
|
1678
|
+
encoding: "utf8"
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
async deleteAuthSecret() {
|
|
1682
|
+
try {
|
|
1683
|
+
await fsPromises.unlink(this.credentialsPath);
|
|
1684
|
+
} catch (error) {
|
|
1685
|
+
const nodeError = error;
|
|
1686
|
+
if (nodeError.code === "ENOENT") {
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
logger_1.Logger.getInstance().warn(`Failed to delete credentials at ${this.credentialsPath}: ${nodeError.message}`);
|
|
314
1690
|
}
|
|
315
|
-
}
|
|
1691
|
+
}
|
|
1692
|
+
getSendSourceCode() {
|
|
1693
|
+
const envValue = process.env.DATAFLINT_SEND_SOURCE_CODE;
|
|
1694
|
+
return (envValue == null ? void 0 : envValue.toLowerCase()) === "true";
|
|
1695
|
+
}
|
|
1696
|
+
getM2MMode() {
|
|
1697
|
+
return this.m2mMode;
|
|
1698
|
+
}
|
|
1699
|
+
getTenantId() {
|
|
1700
|
+
return this.config.tenantId;
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
316
1703
|
exports.StandaloneConfigService = StandaloneConfigService;
|
|
317
|
-
//# sourceMappingURL=config.js.map
|
|
1704
|
+
//# sourceMappingURL=config.js.map
|