@dataflint/mcp-server 1.0.15 → 1.0.17

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