@aifabrix/builder 2.42.0 → 2.43.0
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/README.md +1 -1
- package/bin/aifabrix.js +1 -1
- package/integration/hubspot-test/README.md +126 -0
- package/integration/{hubspot → hubspot-test}/application.json +6 -6
- package/integration/{hubspot → hubspot-test}/create-hubspot.js +5 -5
- package/integration/hubspot-test/env.template +4 -0
- package/integration/{hubspot/hubspot-datasource-company.json → hubspot-test/hubspot-test-datasource-company.json} +3 -2
- package/integration/{hubspot/hubspot-datasource-contact.json → hubspot-test/hubspot-test-datasource-contact.json} +3 -2
- package/integration/{hubspot/hubspot-datasource-deal.json → hubspot-test/hubspot-test-datasource-deal.json} +3 -2
- package/integration/{hubspot/hubspot-datasource-users.json → hubspot-test/hubspot-test-datasource-users.json} +3 -2
- package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +198 -21
- package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
- package/integration/hubspot-test/rbac.json +166 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test.js +102 -59
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
- package/lib/api/external-test.api.js +1 -1
- package/lib/api/service-users.api.js +111 -2
- package/lib/api/types/service-users.types.js +41 -0
- package/lib/api/wizard.api.js +2 -1
- package/lib/app/index.js +2 -2
- package/lib/app/prompts.js +2 -2
- package/lib/app/readme.js +3 -1
- package/lib/app/register.js +3 -1
- package/lib/app/rotate-secret.js +3 -0
- package/lib/cli/setup-app.js +5 -5
- package/lib/cli/setup-auth.js +19 -11
- package/lib/cli/setup-dev.js +62 -32
- package/lib/cli/setup-environment.js +6 -21
- package/lib/cli/setup-infra.js +13 -0
- package/lib/cli/setup-secrets.js +45 -6
- package/lib/cli/setup-service-user.js +146 -20
- package/lib/cli/setup-utility.js +12 -0
- package/lib/commands/auth-config.js +25 -19
- package/lib/commands/datasource.js +46 -1
- package/lib/commands/dev-init.js +1 -1
- package/lib/commands/repair-env-template.js +14 -8
- package/lib/commands/repair-rbac.js +25 -19
- package/lib/commands/repair.js +108 -31
- package/lib/commands/secrets-remove.js +1 -1
- package/lib/commands/secrets-set.js +6 -0
- package/lib/commands/secrets-validate.js +17 -4
- package/lib/commands/service-user.js +231 -2
- package/lib/commands/up-common.js +25 -0
- package/lib/commands/up-dataplane.js +91 -7
- package/lib/commands/wizard-core-helpers.js +5 -2
- package/lib/commands/wizard-core.js +2 -1
- package/lib/commands/wizard-headless.js +6 -1
- package/lib/commands/wizard.js +13 -6
- package/lib/core/admin-secrets.js +2 -0
- package/lib/core/config.js +7 -5
- package/lib/core/ensure-encryption-key.js +1 -3
- package/lib/core/secrets.js +32 -9
- package/lib/core/templates.js +1 -1
- package/lib/datasource/abac-validator.js +157 -0
- package/lib/datasource/field-reference-validator.js +74 -36
- package/lib/datasource/log-viewer.js +221 -0
- package/lib/datasource/resolve-app.js +109 -0
- package/lib/datasource/test-e2e.js +11 -20
- package/lib/datasource/test-integration.js +42 -22
- package/lib/datasource/validate.js +5 -2
- package/lib/external-system/download-helpers.js +3 -1
- package/lib/external-system/generator.js +12 -8
- package/lib/external-system/test-system-level.js +1 -1
- package/lib/generator/external-controller-manifest.js +3 -3
- package/lib/generator/external-schema-utils.js +3 -1
- package/lib/generator/external.js +7 -7
- package/lib/generator/helpers.js +13 -9
- package/lib/generator/index.js +4 -4
- package/lib/generator/split.js +45 -10
- package/lib/generator/wizard-prompts-secondary.js +39 -7
- package/lib/generator/wizard-readme.js +4 -1
- package/lib/generator/wizard.js +68 -53
- package/lib/infrastructure/helpers.js +50 -35
- package/lib/infrastructure/index.js +39 -23
- package/lib/schema/env-config.yaml +19 -2
- package/lib/schema/external-datasource.schema.json +11 -1
- package/lib/schema/wizard-config.schema.json +7 -1
- package/lib/utils/app-config-resolver.js +23 -1
- package/lib/utils/config-paths.js +48 -4
- package/lib/utils/credential-secrets-env.js +16 -1
- package/lib/utils/env-map.js +7 -3
- package/lib/utils/error-formatter.js +37 -0
- package/lib/utils/external-env-template.js +180 -0
- package/lib/utils/external-readme.js +33 -1
- package/lib/utils/external-system-display.js +43 -0
- package/lib/utils/external-system-validators.js +2 -2
- package/lib/utils/help-builder.js +3 -5
- package/lib/utils/local-secrets.js +26 -3
- package/lib/utils/paths.js +2 -1
- package/lib/utils/secrets-generator.js +2 -2
- package/lib/utils/secrets-utils.js +4 -0
- package/lib/utils/secure-file-permissions.js +91 -0
- package/lib/utils/token-manager.js +36 -3
- package/lib/utils/yaml-preserve.js +59 -1
- package/lib/validation/env-template-auth.js +50 -2
- package/lib/validation/external-manifest-validator.js +8 -0
- package/lib/validation/validate.js +8 -0
- package/lib/validation/validator.js +10 -13
- package/package.json +6 -2
- package/templates/applications/dataplane/env.template +5 -1
- package/templates/applications/miso-controller/application.yaml +1 -1
- package/templates/applications/miso-controller/env.template +13 -2
- package/templates/external-system/README.md.hbs +18 -5
- package/templates/external-system/env.template.hbs +22 -0
- package/integration/hubspot/README.md +0 -100
- package/integration/hubspot/env.template +0 -4
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +0 -0
|
@@ -12,7 +12,7 @@ const fs = require('fs');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const Ajv = require('ajv');
|
|
14
14
|
const { detectAppType, getDeployJsonPath } = require('../utils/paths');
|
|
15
|
-
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
15
|
+
const { resolveApplicationConfigPath, resolveRbacPath } = require('../utils/app-config-resolver');
|
|
16
16
|
const { loadConfigFile } = require('../utils/config-format');
|
|
17
17
|
const { loadVariables, loadRbac } = require('./helpers');
|
|
18
18
|
const {
|
|
@@ -117,9 +117,9 @@ async function generateExternalSystemDeployJson(appName, appPath) {
|
|
|
117
117
|
const systemFilePath = resolveSystemFilePath(variables, appPath, appName);
|
|
118
118
|
const systemJson = await loadSystemFileContent(systemFilePath);
|
|
119
119
|
|
|
120
|
-
// Load
|
|
121
|
-
const rbacPath =
|
|
122
|
-
const rbac = loadRbac(rbacPath);
|
|
120
|
+
// Load RBAC from app directory (rbac.yaml, rbac.yml, or rbac.json)
|
|
121
|
+
const rbacPath = resolveRbacPath(appPath);
|
|
122
|
+
const rbac = rbacPath ? loadRbac(rbacPath) : null;
|
|
123
123
|
mergeRbacIntoSystemJson(systemJson, rbac);
|
|
124
124
|
|
|
125
125
|
// Write it as <app-name>-deploy.json (consistent naming)
|
|
@@ -153,9 +153,9 @@ async function loadSystemFile(appPath, schemaBasePath, systemFileName) {
|
|
|
153
153
|
|
|
154
154
|
const systemJson = loadConfigFile(systemFilePath);
|
|
155
155
|
|
|
156
|
-
// Load
|
|
157
|
-
const rbacPath =
|
|
158
|
-
const rbac = loadRbac(rbacPath);
|
|
156
|
+
// Load RBAC from app directory (rbac.yaml, rbac.yml, or rbac.json) and merge if present
|
|
157
|
+
const rbacPath = resolveRbacPath(appPath);
|
|
158
|
+
const rbac = rbacPath ? loadRbac(rbacPath) : null;
|
|
159
159
|
if (rbac) {
|
|
160
160
|
if (rbac.roles && (!systemJson.roles || systemJson.roles.length === 0)) {
|
|
161
161
|
systemJson.roles = rbac.roles;
|
package/lib/generator/helpers.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
|
-
const
|
|
12
|
+
const path = require('path');
|
|
13
13
|
const { loadConfigFile } = require('../utils/config-format');
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -37,21 +37,25 @@ function loadEnvTemplate(templatePath) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Loads rbac.yaml
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* @
|
|
40
|
+
* Loads RBAC config file (rbac.yaml, rbac.yml, or rbac.json) if it exists.
|
|
41
|
+
* Uses loadConfigFile so format is inferred from extension.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} rbacPath - Path to RBAC file (e.g. from resolveRbacPath)
|
|
44
|
+
* @returns {Object|null} Parsed RBAC configuration or null if path is falsy or file does not exist
|
|
45
|
+
* @throws {Error} If file exists but has invalid syntax (message references actual filename, e.g. rbac.json)
|
|
44
46
|
*/
|
|
45
47
|
function loadRbac(rbacPath) {
|
|
48
|
+
if (!rbacPath || typeof rbacPath !== 'string') {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
46
51
|
if (!fs.existsSync(rbacPath)) {
|
|
47
52
|
return null;
|
|
48
53
|
}
|
|
49
|
-
|
|
50
|
-
const rbacContent = fs.readFileSync(rbacPath, 'utf8');
|
|
51
54
|
try {
|
|
52
|
-
return
|
|
55
|
+
return loadConfigFile(rbacPath);
|
|
53
56
|
} catch (error) {
|
|
54
|
-
|
|
57
|
+
const basename = path.basename(rbacPath);
|
|
58
|
+
throw new Error(`Invalid syntax in ${basename}: ${error.message}`);
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
|
package/lib/generator/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const fs = require('fs');
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const _validator = require('../validation/validator');
|
|
15
15
|
const builders = require('./builders');
|
|
16
|
-
const { detectAppType, getDeployJsonPath, resolveApplicationConfigPath } = require('../utils/paths');
|
|
16
|
+
const { detectAppType, getDeployJsonPath, resolveApplicationConfigPath, resolveRbacPath } = require('../utils/paths');
|
|
17
17
|
const { logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
18
18
|
const splitFunctions = require('./split');
|
|
19
19
|
const { loadVariables, loadEnvTemplate, loadRbac, parseEnvironmentVariables } = require('./helpers');
|
|
@@ -39,7 +39,7 @@ const { buildEnvVarMap } = require('../utils/env-map');
|
|
|
39
39
|
*
|
|
40
40
|
* @example
|
|
41
41
|
* const jsonPath = await generateDeployJson('myapp');
|
|
42
|
-
* // Returns: './builder/myapp/myapp-deploy.json' or './integration/hubspot/application-schema.json'
|
|
42
|
+
* // Returns: './builder/myapp/myapp-deploy.json' or './integration/hubspot-test/application-schema.json'
|
|
43
43
|
*/
|
|
44
44
|
/**
|
|
45
45
|
* Loads configuration files for deployment generation
|
|
@@ -51,12 +51,12 @@ const { buildEnvVarMap } = require('../utils/env-map');
|
|
|
51
51
|
function loadDeploymentConfigFiles(appPath, appType, appName) {
|
|
52
52
|
const variablesPath = resolveApplicationConfigPath(appPath);
|
|
53
53
|
const templatePath = path.join(appPath, 'env.template');
|
|
54
|
-
const rbacPath =
|
|
54
|
+
const rbacPath = resolveRbacPath(appPath);
|
|
55
55
|
const jsonPath = getDeployJsonPath(appName, appType, true); // Use new naming
|
|
56
56
|
|
|
57
57
|
const { parsed: variables } = loadVariables(variablesPath);
|
|
58
58
|
const envTemplate = loadEnvTemplate(templatePath);
|
|
59
|
-
const rbac = loadRbac(rbacPath);
|
|
59
|
+
const rbac = rbacPath ? loadRbac(rbacPath) : null;
|
|
60
60
|
|
|
61
61
|
return { variables, envTemplate, rbac, jsonPath };
|
|
62
62
|
}
|
package/lib/generator/split.js
CHANGED
|
@@ -14,6 +14,7 @@ const yaml = require('js-yaml');
|
|
|
14
14
|
const { parseImageReference } = require('./parse-image');
|
|
15
15
|
const { generateReadmeFromDeployJson } = require('./split-readme');
|
|
16
16
|
const { extractVariablesYaml, getExternalDatasourceFileName } = require('./split-variables');
|
|
17
|
+
const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Converts configuration array back to env.template format
|
|
@@ -207,24 +208,49 @@ function mergeEnvTemplateWithExisting(existingContent, expectedByKey) {
|
|
|
207
208
|
return updatedLines.join('\n') + (updatedLines.length > 0 ? '\n' : '');
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Builds key -> line map from env.template content (for merge when using external system template).
|
|
213
|
+
* @param {string} content - Full env.template content
|
|
214
|
+
* @returns {Map<string, string>} Key to full KEY=value line
|
|
215
|
+
*/
|
|
216
|
+
function buildExpectedByKeyFromEnvContent(content) {
|
|
217
|
+
const expectedByKey = new Map();
|
|
218
|
+
if (!content || typeof content !== 'string') return expectedByKey;
|
|
219
|
+
const lines = content.split(/\r?\n/);
|
|
220
|
+
for (const line of lines) {
|
|
221
|
+
const trimmed = line.trim();
|
|
222
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
223
|
+
const eq = trimmed.indexOf('=');
|
|
224
|
+
if (eq > 0) {
|
|
225
|
+
const key = trimmed.substring(0, eq).trim();
|
|
226
|
+
expectedByKey.set(key, trimmed);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return expectedByKey;
|
|
230
|
+
}
|
|
231
|
+
|
|
210
232
|
/**
|
|
211
233
|
* Writes env.template (merge or overwrite).
|
|
212
234
|
* @param {string} outputDir - Output directory
|
|
213
235
|
* @param {string} envTemplate - Default env.template content
|
|
214
|
-
* @param {Object} options - Options (mergeEnvTemplate, configuration)
|
|
236
|
+
* @param {Object} options - Options (mergeEnvTemplate, configuration, expectedByKey for external)
|
|
215
237
|
* @returns {Promise<string>} Path to env.template
|
|
216
238
|
*/
|
|
217
239
|
async function writeEnvTemplateToDir(outputDir, envTemplate, options) {
|
|
218
240
|
const envTemplatePath = path.join(outputDir, 'env.template');
|
|
219
241
|
const fsSync = require('fs');
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
242
|
+
const useMerge = options.mergeEnvTemplate && fsSync.existsSync(envTemplatePath);
|
|
243
|
+
if (useMerge) {
|
|
244
|
+
const expectedByKey = options.expectedByKey ||
|
|
245
|
+
(options.configuration ? buildEnvTemplateExpectedByKey(options.configuration) : new Map());
|
|
246
|
+
if (expectedByKey.size > 0) {
|
|
247
|
+
const existingContent = await fs.readFile(envTemplatePath, 'utf8');
|
|
248
|
+
const merged = mergeEnvTemplateWithExisting(existingContent, expectedByKey);
|
|
249
|
+
await writeComponentFile(envTemplatePath, merged);
|
|
250
|
+
return envTemplatePath;
|
|
251
|
+
}
|
|
227
252
|
}
|
|
253
|
+
await writeComponentFile(envTemplatePath, envTemplate);
|
|
228
254
|
return envTemplatePath;
|
|
229
255
|
}
|
|
230
256
|
|
|
@@ -401,12 +427,21 @@ async function splitDeployJson(deployJsonPath, outputDir = null, splitOptions =
|
|
|
401
427
|
normalizeDeploymentForSplit(deployment);
|
|
402
428
|
|
|
403
429
|
const configArray = deployment.configuration || [];
|
|
404
|
-
|
|
430
|
+
let envTemplate;
|
|
431
|
+
const writeOptions = buildSplitWriteOptions(splitOptions, configArray);
|
|
432
|
+
if (deployment.system && typeof deployment.system === 'object') {
|
|
433
|
+
envTemplate = generateExternalEnvTemplateContent(deployment.system);
|
|
434
|
+
if (writeOptions.mergeEnvTemplate) {
|
|
435
|
+
writeOptions.expectedByKey = buildExpectedByKeyFromEnvContent(envTemplate);
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
envTemplate = extractEnvTemplate(configArray);
|
|
439
|
+
}
|
|
440
|
+
|
|
405
441
|
const variables = extractVariablesYaml(deployment);
|
|
406
442
|
const rbac = extractRbacYaml(deployment);
|
|
407
443
|
const readme = generateReadmeFromDeployJson(deployment);
|
|
408
444
|
|
|
409
|
-
const writeOptions = buildSplitWriteOptions(splitOptions, configArray);
|
|
410
445
|
const result = await writeComponentFiles(finalOutputDir, envTemplate, variables, rbac, readme, writeOptions);
|
|
411
446
|
await applyExternalSystemFilesToResult(finalOutputDir, deployment, result);
|
|
412
447
|
return result;
|
|
@@ -107,6 +107,16 @@ async function promptForEntitySelection(entities = []) {
|
|
|
107
107
|
/** @param {*} o - Value to stringify */
|
|
108
108
|
const _s = (o) => (o === null || o === undefined || o === '' ? '—' : String(o));
|
|
109
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Humanize app key for display name (must stay in sync with prepareWizardContext in lib/generator/wizard.js).
|
|
112
|
+
* @param {string} appKey - Application key (e.g. hubspot-demo)
|
|
113
|
+
* @returns {string} Display name (e.g. Hubspot Demo)
|
|
114
|
+
*/
|
|
115
|
+
function humanizeAppKey(appKey) {
|
|
116
|
+
if (!appKey || typeof appKey !== 'string') return appKey || '';
|
|
117
|
+
return appKey.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
118
|
+
}
|
|
119
|
+
|
|
110
120
|
/** @param {Object} sys - systemSummary */
|
|
111
121
|
function _formatSystem(sys) {
|
|
112
122
|
return [
|
|
@@ -149,8 +159,11 @@ function _formatFieldMappings(fm) {
|
|
|
149
159
|
/**
|
|
150
160
|
* Derive a preview summary from systemConfig and datasourceConfigs when the dataplane
|
|
151
161
|
* preview API does not return summaries. Ensures a compact summary is always shown.
|
|
162
|
+
* When appKey is provided, system key/displayName and datasource keys are overridden
|
|
163
|
+
* to match what prepareWizardContext will write (so the preview matches saved files).
|
|
152
164
|
* @param {Object} systemConfig - System configuration
|
|
153
165
|
* @param {Object[]} datasourceConfigs - Array of datasource configurations
|
|
166
|
+
* @param {string} [appKey] - Optional app key; when set, overrides system key/displayName and rewrites datasource keys
|
|
154
167
|
* @returns {Object} Preview object compatible with formatPreviewSummary
|
|
155
168
|
*/
|
|
156
169
|
function _buildDatasourceSummary(ds) {
|
|
@@ -171,8 +184,9 @@ function _buildDatasourceSummary(ds) {
|
|
|
171
184
|
}
|
|
172
185
|
|
|
173
186
|
function _buildSystemSummary(sys) {
|
|
174
|
-
const baseUrl = sys.openapi?.servers?.[0]?.url ?? sys.baseUrl ?? sys.openapi?.baseUrl ??
|
|
175
|
-
|
|
187
|
+
const baseUrl = sys.openapi?.servers?.[0]?.url ?? sys.baseUrl ?? sys.openapi?.baseUrl ??
|
|
188
|
+
sys.authentication?.variables?.baseUrl ?? null;
|
|
189
|
+
const authType = sys.authentication?.type ?? sys.authentication?.method ?? sys.authenticationType ?? null;
|
|
176
190
|
const endpointCount = sys.openapi?.endpoints?.length ??
|
|
177
191
|
(sys.openapi?.operations ? Object.keys(sys.openapi.operations || {}).length : null);
|
|
178
192
|
return {
|
|
@@ -191,7 +205,7 @@ function _buildFieldMappingsSummary(ds0) {
|
|
|
191
205
|
return mappedFields.length > 0 ? { mappingCount: mappedFields.length, mappedFields, unmappedFields: [] } : null;
|
|
192
206
|
}
|
|
193
207
|
|
|
194
|
-
function derivePreviewFromConfig(systemConfig, datasourceConfigs) {
|
|
208
|
+
function derivePreviewFromConfig(systemConfig, datasourceConfigs, appKey) {
|
|
195
209
|
const sys = systemConfig || {};
|
|
196
210
|
const dsList = Array.isArray(datasourceConfigs) ? datasourceConfigs : (datasourceConfigs ? [datasourceConfigs] : []);
|
|
197
211
|
|
|
@@ -199,7 +213,23 @@ function derivePreviewFromConfig(systemConfig, datasourceConfigs) {
|
|
|
199
213
|
systemSummary: _buildSystemSummary(sys),
|
|
200
214
|
fieldMappingsSummary: _buildFieldMappingsSummary(dsList[0] || {})
|
|
201
215
|
};
|
|
202
|
-
|
|
216
|
+
let datasourceSummaries = dsList.map(_buildDatasourceSummary);
|
|
217
|
+
|
|
218
|
+
if (appKey && typeof appKey === 'string') {
|
|
219
|
+
result.systemSummary.key = appKey;
|
|
220
|
+
result.systemSummary.displayName = humanizeAppKey(appKey);
|
|
221
|
+
const originalSystemKey = sys.key || appKey;
|
|
222
|
+
const originalPrefix = `${originalSystemKey}-`;
|
|
223
|
+
datasourceSummaries = datasourceSummaries.map((summary, i) => {
|
|
224
|
+
const ds = dsList[i] || {};
|
|
225
|
+
const dsKey = ds.key || '';
|
|
226
|
+
const newKey = dsKey && dsKey.startsWith(originalPrefix)
|
|
227
|
+
? `${appKey}-${dsKey.substring(originalPrefix.length)}`
|
|
228
|
+
: `${appKey}-${ds.entityType || ds.entityKey || (dsKey && dsKey.split('-').pop()) || 'default'}`;
|
|
229
|
+
return { ...summary, key: newKey };
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
203
233
|
if (datasourceSummaries.length === 1) {
|
|
204
234
|
result.datasourceSummary = datasourceSummaries[0];
|
|
205
235
|
} else if (datasourceSummaries.length > 1) {
|
|
@@ -247,11 +277,12 @@ function formatPreviewSummary(preview) {
|
|
|
247
277
|
* @param {Object|null} [opts.preview] - Preview data from getPreview (null = fallback to YAML)
|
|
248
278
|
* @param {Object} opts.systemConfig - System configuration
|
|
249
279
|
* @param {Object[]} opts.datasourceConfigs - Array of datasource configurations
|
|
280
|
+
* @param {string} [opts.appKey] - App key; when set and using fallback preview, overrides system key/displayName and datasource keys
|
|
250
281
|
* @returns {Promise<Object>} Object with action ('accept'|'cancel') and optionally edited configs
|
|
251
282
|
*/
|
|
252
|
-
async function promptForConfigReview({ preview, systemConfig, datasourceConfigs }) {
|
|
283
|
+
async function promptForConfigReview({ preview, systemConfig, datasourceConfigs, appKey }) {
|
|
253
284
|
const hasSummary = preview && (preview.systemSummary || preview.datasourceSummary || (preview.datasourceSummaries && preview.datasourceSummaries.length > 0));
|
|
254
|
-
const summaryToShow = hasSummary ? preview : derivePreviewFromConfig(systemConfig, datasourceConfigs);
|
|
285
|
+
const summaryToShow = hasSummary ? preview : derivePreviewFromConfig(systemConfig, datasourceConfigs, appKey);
|
|
255
286
|
const canShowSummary = summaryToShow.systemSummary || summaryToShow.datasourceSummary ||
|
|
256
287
|
(summaryToShow.datasourceSummaries && summaryToShow.datasourceSummaries.length > 0);
|
|
257
288
|
|
|
@@ -290,5 +321,6 @@ module.exports = {
|
|
|
290
321
|
promptForEntitySelection,
|
|
291
322
|
promptForConfigReview,
|
|
292
323
|
derivePreviewFromConfig,
|
|
293
|
-
formatPreviewSummary
|
|
324
|
+
formatPreviewSummary,
|
|
325
|
+
humanizeAppKey
|
|
294
326
|
};
|
|
@@ -68,6 +68,8 @@ async function generateReadme(options) {
|
|
|
68
68
|
};
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
+
const auth = systemConfig.authentication || systemConfig.auth || {};
|
|
72
|
+
const authType = auth.type || auth.method || auth.authType;
|
|
71
73
|
const readmeContent = generateExternalReadmeContent({
|
|
72
74
|
appName,
|
|
73
75
|
systemKey,
|
|
@@ -75,7 +77,8 @@ async function generateReadme(options) {
|
|
|
75
77
|
displayName: systemConfig.displayName,
|
|
76
78
|
description: systemConfig.description,
|
|
77
79
|
fileExt: ext,
|
|
78
|
-
datasources
|
|
80
|
+
datasources,
|
|
81
|
+
authType
|
|
79
82
|
});
|
|
80
83
|
|
|
81
84
|
await fs.writeFile(readmePath, readmeContent, 'utf8');
|
package/lib/generator/wizard.js
CHANGED
|
@@ -15,7 +15,8 @@ const chalk = require('chalk');
|
|
|
15
15
|
const logger = require('../utils/logger');
|
|
16
16
|
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
17
17
|
const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
|
|
18
|
-
const { systemKeyToKvPrefix } = require('../utils/credential-secrets-env');
|
|
18
|
+
const { systemKeyToKvPrefix, securityKeyToVar, isValidKvPath } = require('../utils/credential-secrets-env');
|
|
19
|
+
const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
|
|
19
20
|
const { generateReadme } = require('./wizard-readme');
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -130,10 +131,12 @@ async function generateConfigFilesForWizard(params) {
|
|
|
130
131
|
format: format || 'yaml'
|
|
131
132
|
});
|
|
132
133
|
|
|
133
|
-
// Generate env.template with
|
|
134
|
-
await generateEnvTemplate(appPath, systemConfig, finalSystemKey);
|
|
135
|
-
|
|
134
|
+
// Generate env.template with Authentication and Configuration sections (Handlebars)
|
|
136
135
|
const envTemplatePath = path.join(appPath, 'env.template');
|
|
136
|
+
const envTemplateContent = generateExternalEnvTemplateContent(systemConfig);
|
|
137
|
+
await fs.writeFile(envTemplatePath, envTemplateContent, 'utf8');
|
|
138
|
+
logger.log(chalk.green('✓ Generated env.template'));
|
|
139
|
+
|
|
137
140
|
try {
|
|
138
141
|
const secretsEnsure = require('../core/secrets-ensure');
|
|
139
142
|
await secretsEnsure.ensureSecretsFromEnvTemplate(envTemplatePath, { emptyValuesForCredentials: true });
|
|
@@ -297,72 +300,84 @@ async function generateOrUpdateVariablesYaml(params) {
|
|
|
297
300
|
}
|
|
298
301
|
}
|
|
299
302
|
|
|
300
|
-
/**
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
* @param {string} prefix - KV prefix (e.g. HUBSPOT)
|
|
304
|
-
*/
|
|
305
|
-
function addApiKeyAuthLines(lines, prefix) {
|
|
306
|
-
lines.push('# API Key Authentication');
|
|
307
|
-
lines.push(`KV_${prefix}_APIKEY=`);
|
|
308
|
-
lines.push('');
|
|
303
|
+
/** Path-style kv value: kv://systemKey/key (camelCase key). */
|
|
304
|
+
function toPathStyleKv(systemKey, key) {
|
|
305
|
+
return `kv://${systemKey}/${key}`;
|
|
309
306
|
}
|
|
310
307
|
|
|
311
308
|
/**
|
|
312
|
-
* Adds
|
|
309
|
+
* Adds env.template lines from authentication.security (path-style kv:// values).
|
|
313
310
|
* @param {Array<string>} lines - Lines array to append to
|
|
314
|
-
* @param {Object}
|
|
315
|
-
* @param {string}
|
|
311
|
+
* @param {Object} security - authentication.security object
|
|
312
|
+
* @param {string} systemKey - System key for path namespace
|
|
313
|
+
* @param {string} prefix - KV prefix (e.g. HUBSPOT)
|
|
316
314
|
*/
|
|
317
|
-
function
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
315
|
+
function addLinesFromSecurity(lines, security, systemKey, prefix) {
|
|
316
|
+
if (!security || typeof security !== 'object') return;
|
|
317
|
+
for (const key of Object.keys(security)) {
|
|
318
|
+
const envName = `KV_${prefix}_${securityKeyToVar(key)}`;
|
|
319
|
+
let value = security[key];
|
|
320
|
+
if (typeof value === 'string' && value.trim().startsWith('kv://') && isValidKvPath(value.trim())) {
|
|
321
|
+
value = value.trim();
|
|
322
|
+
} else {
|
|
323
|
+
value = toPathStyleKv(systemKey, key);
|
|
324
|
+
}
|
|
325
|
+
lines.push(`${envName}=${value}`);
|
|
326
|
+
}
|
|
327
|
+
if (Object.keys(security).length > 0) lines.push('');
|
|
323
328
|
}
|
|
324
329
|
|
|
325
|
-
/**
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
330
|
+
/** Fallback security keys by auth method (camelCase) for path-style kv://. */
|
|
331
|
+
const FALLBACK_SECURITY_BY_AUTH = {
|
|
332
|
+
oauth2: ['clientId', 'clientSecret'],
|
|
333
|
+
oauth: ['clientId', 'clientSecret'],
|
|
334
|
+
aad: ['clientId', 'clientSecret'],
|
|
335
|
+
apikey: ['apiKey'],
|
|
336
|
+
apiKey: ['apiKey'],
|
|
337
|
+
basic: ['username', 'password'],
|
|
338
|
+
queryParam: ['paramValue'],
|
|
339
|
+
oidc: [],
|
|
340
|
+
hmac: ['signingSecret'],
|
|
341
|
+
bearer: ['bearerToken'],
|
|
342
|
+
token: ['bearerToken'],
|
|
343
|
+
none: []
|
|
344
|
+
};
|
|
335
345
|
|
|
336
346
|
/**
|
|
337
|
-
* Adds
|
|
347
|
+
* Adds auth lines by type with path-style kv:// values (fallback when security is absent).
|
|
338
348
|
* @param {Array<string>} lines - Lines array to append to
|
|
349
|
+
* @param {string} authType - Authentication type
|
|
350
|
+
* @param {string} systemKey - System key
|
|
339
351
|
* @param {string} prefix - KV prefix
|
|
340
352
|
*/
|
|
341
|
-
function
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
353
|
+
function addFallbackAuthLines(lines, authType, systemKey, prefix) {
|
|
354
|
+
const keys = FALLBACK_SECURITY_BY_AUTH[authType] || FALLBACK_SECURITY_BY_AUTH.apikey;
|
|
355
|
+
if (keys.length === 0) return;
|
|
356
|
+
const labels = { oauth2: 'OAuth2', aad: 'Azure AD', apikey: 'API Key', basic: 'Basic', queryParam: 'Query Param', hmac: 'HMAC', bearer: 'Bearer Token' };
|
|
357
|
+
const label = labels[authType] || authType;
|
|
358
|
+
lines.push(`# ${label} Authentication`);
|
|
359
|
+
for (const key of keys) {
|
|
360
|
+
lines.push(`KV_${prefix}_${securityKeyToVar(key)}=${toPathStyleKv(systemKey, key)}`);
|
|
361
|
+
}
|
|
345
362
|
lines.push('');
|
|
346
363
|
}
|
|
347
364
|
|
|
348
365
|
/**
|
|
349
|
-
* Adds authentication lines
|
|
366
|
+
* Adds authentication lines: from authentication.security when present, else by auth type with path-style kv://.
|
|
350
367
|
* @param {Array<string>} lines - Lines array to append to
|
|
351
|
-
* @param {Object} auth - Authentication configuration
|
|
352
|
-
* @param {string} authType -
|
|
353
|
-
* @param {string} systemKey - System key
|
|
368
|
+
* @param {Object} auth - Authentication configuration (may have security, type/method)
|
|
369
|
+
* @param {string} authType - Normalized auth type
|
|
370
|
+
* @param {string} systemKey - System key for KV path namespace
|
|
354
371
|
*/
|
|
355
372
|
function addAuthenticationLines(lines, auth, authType, systemKey) {
|
|
356
373
|
const prefix = systemKeyToKvPrefix(systemKey);
|
|
357
374
|
if (!prefix) return;
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
} else
|
|
363
|
-
|
|
364
|
-
} else if (authType === 'basic') {
|
|
365
|
-
addBasicAuthLines(lines, prefix);
|
|
375
|
+
const security = auth?.security;
|
|
376
|
+
if (security && typeof security === 'object' && Object.keys(security).length > 0) {
|
|
377
|
+
lines.push('# Authentication (from security)');
|
|
378
|
+
addLinesFromSecurity(lines, security, systemKey, prefix);
|
|
379
|
+
} else {
|
|
380
|
+
addFallbackAuthLines(lines, authType, systemKey, prefix);
|
|
366
381
|
}
|
|
367
382
|
}
|
|
368
383
|
|
|
@@ -381,22 +396,22 @@ function addBaseUrlLines(lines, systemConfig) {
|
|
|
381
396
|
}
|
|
382
397
|
|
|
383
398
|
/**
|
|
384
|
-
* Generate env.template with KV_* authentication variables
|
|
399
|
+
* Generate env.template with KV_* authentication variables (legacy; prefer generateExternalEnvTemplateContent).
|
|
385
400
|
* @async
|
|
386
|
-
* @function
|
|
401
|
+
* @function _generateEnvTemplate
|
|
387
402
|
* @param {string} appPath - Application directory path
|
|
388
403
|
* @param {Object} systemConfig - System configuration (must have key for systemKey)
|
|
389
404
|
* @param {string} [finalSystemKey] - Final system key for KV_ prefix (default: systemConfig.key)
|
|
390
405
|
* @throws {Error} If generation fails
|
|
391
406
|
*/
|
|
392
|
-
async function
|
|
407
|
+
async function _generateEnvTemplate(appPath, systemConfig, finalSystemKey) {
|
|
393
408
|
try {
|
|
394
409
|
const envTemplatePath = path.join(appPath, 'env.template');
|
|
395
410
|
const systemKey = finalSystemKey || systemConfig?.key;
|
|
396
411
|
const lines = ['# Environment variables for external system integration', '# Use KV_* for credential push (aifabrix credential push)', ''];
|
|
397
412
|
|
|
398
413
|
const auth = systemConfig?.authentication || systemConfig?.auth || {};
|
|
399
|
-
const authType = auth.type || auth.authType || 'apikey';
|
|
414
|
+
const authType = (auth.type || auth.method || auth.authType || 'apikey').toLowerCase();
|
|
400
415
|
|
|
401
416
|
addAuthenticationLines(lines, auth, authType, systemKey);
|
|
402
417
|
addBaseUrlLines(lines, systemConfig);
|
|
@@ -14,6 +14,7 @@ const fs = require('fs');
|
|
|
14
14
|
const chalk = require('chalk');
|
|
15
15
|
const handlebars = require('handlebars');
|
|
16
16
|
const secrets = require('../core/secrets');
|
|
17
|
+
const adminSecrets = require('../core/admin-secrets');
|
|
17
18
|
const logger = require('../utils/logger');
|
|
18
19
|
const dockerUtils = require('../utils/docker');
|
|
19
20
|
const paths = require('../utils/paths');
|
|
@@ -69,19 +70,6 @@ function logVolumeResetHint(infraDir) {
|
|
|
69
70
|
));
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
/**
|
|
73
|
-
* Apply password to admin-secrets file content (all three password keys).
|
|
74
|
-
* @param {string} content - Current file content
|
|
75
|
-
* @param {string} password - Password to set
|
|
76
|
-
* @returns {string} Updated content
|
|
77
|
-
*/
|
|
78
|
-
function applyPasswordToAdminSecretsContent(content, password) {
|
|
79
|
-
return content
|
|
80
|
-
.replace(/^POSTGRES_PASSWORD=.*$/m, `POSTGRES_PASSWORD=${password}`)
|
|
81
|
-
.replace(/^PGADMIN_DEFAULT_PASSWORD=.*$/m, `PGADMIN_DEFAULT_PASSWORD=${password}`)
|
|
82
|
-
.replace(/^REDIS_COMMANDER_PASSWORD=.*$/m, `REDIS_COMMANDER_PASSWORD=${password}`);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
73
|
/**
|
|
86
74
|
* Sync postgres-passwordKeyVault to the main secrets store (file or remote).
|
|
87
75
|
* @param {string} password - Password to store
|
|
@@ -94,10 +82,42 @@ async function syncPostgresPasswordToStore(password) {
|
|
|
94
82
|
}
|
|
95
83
|
}
|
|
96
84
|
|
|
85
|
+
/** Default admin env keys and values when missing. */
|
|
86
|
+
const DEFAULT_ADMIN_OBJ = {
|
|
87
|
+
PGADMIN_DEFAULT_EMAIL: 'admin@aifabrix.dev',
|
|
88
|
+
REDIS_HOST: 'local:redis:6379:0:',
|
|
89
|
+
REDIS_COMMANDER_USER: 'admin'
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Writes merged admin secrets to disk and logs/syncs as needed.
|
|
94
|
+
* @async
|
|
95
|
+
* @param {string} adminSecretsPath - Path to admin-secrets.env
|
|
96
|
+
* @param {Object} adminObj - Decrypted admin secrets object
|
|
97
|
+
* @param {string} passwordToUse - Password to set for Postgres, pgAdmin, Redis Commander
|
|
98
|
+
* @param {boolean} shouldOverwriteWithAdminPwd - Whether this was an explicit admin password update
|
|
99
|
+
*/
|
|
100
|
+
async function applyAdminSecretsUpdate(adminSecretsPath, adminObj, passwordToUse, shouldOverwriteWithAdminPwd) {
|
|
101
|
+
const merged = { ...DEFAULT_ADMIN_OBJ, ...adminObj };
|
|
102
|
+
merged.POSTGRES_PASSWORD = passwordToUse;
|
|
103
|
+
merged.PGADMIN_DEFAULT_PASSWORD = passwordToUse;
|
|
104
|
+
merged.REDIS_COMMANDER_PASSWORD = passwordToUse;
|
|
105
|
+
const content = await secrets.formatAdminSecretsContent(merged);
|
|
106
|
+
fs.writeFileSync(adminSecretsPath, content, { mode: 0o600 });
|
|
107
|
+
if (shouldOverwriteWithAdminPwd) {
|
|
108
|
+
logger.log('Updated admin password in admin-secrets.env.');
|
|
109
|
+
await syncPostgresPasswordToStore(passwordToUse);
|
|
110
|
+
logVolumeResetHint(path.join(paths.getAifabrixHome(), getInfraDirName(0)));
|
|
111
|
+
} else {
|
|
112
|
+
logger.log('Set default admin password in admin-secrets.env for local use.');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
97
116
|
/**
|
|
98
117
|
* Ensure admin secrets file exists and set admin password.
|
|
99
118
|
* When adminPwd is provided, update POSTGRES_PASSWORD, PGADMIN_DEFAULT_PASSWORD, REDIS_COMMANDER_PASSWORD
|
|
100
119
|
* in admin-secrets.env (overwrites existing values). Otherwise only backfill empty fields.
|
|
120
|
+
* Reads and writes using decrypted values; writes encrypted when secrets-encryption key is set.
|
|
101
121
|
*
|
|
102
122
|
* @async
|
|
103
123
|
* @param {Object} [options] - Options
|
|
@@ -109,29 +129,25 @@ async function ensureAdminSecrets(options = {}) {
|
|
|
109
129
|
? options.adminPwd.trim()
|
|
110
130
|
: null;
|
|
111
131
|
const passwordToUse = adminPwdOverride || DEFAULT_ADMIN_PASSWORD;
|
|
112
|
-
|
|
113
132
|
const adminSecretsPath = path.join(paths.getAifabrixHome(), 'admin-secrets.env');
|
|
133
|
+
|
|
114
134
|
if (!fs.existsSync(adminSecretsPath)) {
|
|
115
135
|
logger.log('Generating admin-secrets.env...');
|
|
116
136
|
await secrets.generateAdminSecretsEnv(undefined);
|
|
137
|
+
return adminSecretsPath;
|
|
117
138
|
}
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
139
|
+
|
|
140
|
+
const adminObj = await adminSecrets.readAndDecryptAdminSecrets(adminSecretsPath);
|
|
141
|
+
const needsBackfill = !(adminObj.POSTGRES_PASSWORD && adminObj.POSTGRES_PASSWORD.trim()) ||
|
|
142
|
+
!(adminObj.PGADMIN_DEFAULT_PASSWORD && adminObj.PGADMIN_DEFAULT_PASSWORD.trim()) ||
|
|
143
|
+
!(adminObj.REDIS_COMMANDER_PASSWORD && adminObj.REDIS_COMMANDER_PASSWORD.trim());
|
|
122
144
|
const shouldOverwriteWithAdminPwd = adminPwdOverride !== null;
|
|
123
145
|
|
|
124
|
-
if (shouldOverwriteWithAdminPwd) {
|
|
125
|
-
|
|
126
|
-
fs.writeFileSync(adminSecretsPath, content, { mode: 0o600 });
|
|
127
|
-
logger.log('Updated admin password in admin-secrets.env.');
|
|
128
|
-
await syncPostgresPasswordToStore(passwordToUse);
|
|
129
|
-
logVolumeResetHint(path.join(paths.getAifabrixHome(), getInfraDirName(0)));
|
|
130
|
-
} else if (needsBackfill) {
|
|
131
|
-
content = applyPasswordToAdminSecretsContent(content, passwordToUse);
|
|
132
|
-
fs.writeFileSync(adminSecretsPath, content, { mode: 0o600 });
|
|
133
|
-
logger.log('Set default admin password in admin-secrets.env for local use.');
|
|
146
|
+
if (!shouldOverwriteWithAdminPwd && !needsBackfill) {
|
|
147
|
+
return adminSecretsPath;
|
|
134
148
|
}
|
|
149
|
+
|
|
150
|
+
await applyAdminSecretsUpdate(adminSecretsPath, adminObj, passwordToUse, shouldOverwriteWithAdminPwd);
|
|
135
151
|
return adminSecretsPath;
|
|
136
152
|
}
|
|
137
153
|
|
|
@@ -243,12 +259,13 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "miso" -c "GRANT AL
|
|
|
243
259
|
}
|
|
244
260
|
|
|
245
261
|
/**
|
|
246
|
-
* Prepare infrastructure directory and extract postgres password
|
|
262
|
+
* Prepare infrastructure directory and extract postgres password from decrypted admin secrets.
|
|
263
|
+
* @async
|
|
247
264
|
* @param {string} devId - Developer ID
|
|
248
265
|
* @param {string} adminSecretsPath - Path to admin secrets file
|
|
249
|
-
* @returns {Object} Object with infraDir and postgresPassword
|
|
266
|
+
* @returns {Promise<Object>} Object with infraDir and postgresPassword
|
|
250
267
|
*/
|
|
251
|
-
function prepareInfraDirectory(devId, adminSecretsPath) {
|
|
268
|
+
async function prepareInfraDirectory(devId, adminSecretsPath) {
|
|
252
269
|
const aifabrixDir = paths.getAifabrixHome();
|
|
253
270
|
const infraDirName = getInfraDirName(devId);
|
|
254
271
|
const infraDir = path.join(aifabrixDir, infraDirName);
|
|
@@ -265,10 +282,8 @@ function prepareInfraDirectory(devId, adminSecretsPath) {
|
|
|
265
282
|
}
|
|
266
283
|
}
|
|
267
284
|
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
const raw = postgresPasswordMatch ? postgresPasswordMatch[1] : '';
|
|
271
|
-
const postgresPassword = (raw && raw.trim()) || DEFAULT_ADMIN_PASSWORD;
|
|
285
|
+
const adminObj = await adminSecrets.readAndDecryptAdminSecrets(adminSecretsPath);
|
|
286
|
+
const postgresPassword = (adminObj.POSTGRES_PASSWORD && adminObj.POSTGRES_PASSWORD.trim()) || DEFAULT_ADMIN_PASSWORD;
|
|
272
287
|
generatePgAdminConfig(infraDir, postgresPassword);
|
|
273
288
|
|
|
274
289
|
return { infraDir, postgresPassword };
|