@aifabrix/builder 2.45.5 → 2.47.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/.cursor/rules/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/project-rules.mdc +1 -0
- package/.npmrc.token +1 -0
- package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
- package/.temp/validation/summary.txt +5 -0
- package/README.md +43 -17
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +146 -0
- package/jest.projects.js +65 -136
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/dataplane-health.api.js +19 -7
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/index.js +43 -3
- package/lib/api/lifecycle.api.js +98 -0
- package/lib/api/pipeline.api.js +3 -1
- package/lib/api/records-bulk.api.js +14 -1
- package/lib/api/resource-types.api.js +107 -0
- package/lib/api/runtime-configuration.api.js +72 -0
- package/lib/api/types/resource-types.types.js +45 -0
- package/lib/api/user-groups.api.js +9 -9
- package/lib/api/users.api.js +8 -8
- package/lib/api/validation-runner.js +3 -1
- package/lib/api/wizard.api.js +10 -2
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/down.js +78 -27
- package/lib/app/index.js +2 -2
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/app/run-resolve-image.js +2 -1
- package/lib/app/run-stop-containers.js +113 -0
- package/lib/app/run.js +1 -31
- package/lib/app/show-display.js +35 -0
- package/lib/app/show.js +32 -1
- package/lib/build/index.js +22 -5
- package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/channels/add-channel.js +348 -0
- package/lib/channels/channel-artifact-generator.js +141 -0
- package/lib/channels/channel-audit.js +101 -0
- package/lib/channels/channel-auth-context.js +37 -0
- package/lib/channels/channel-credential.js +200 -0
- package/lib/channels/channel-display-name.js +64 -0
- package/lib/channels/channel-external-system.js +106 -0
- package/lib/channels/channel-integration-generator.js +274 -0
- package/lib/channels/channel-probe.js +89 -0
- package/lib/channels/channel-runtime-resolver.js +152 -0
- package/lib/channels/channel-status-display.js +141 -0
- package/lib/channels/channel-targets.js +115 -0
- package/lib/cli/index.js +20 -4
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +84 -81
- package/lib/cli/setup-app.help.js +0 -31
- package/lib/cli/setup-app.js +82 -5
- package/lib/cli/setup-app.test-commands.js +5 -57
- package/lib/cli/setup-auth.js +25 -0
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +25 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
- package/lib/cli/setup-infra-up-platform-action.js +2 -1
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +25 -2
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +44 -5
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +4 -239
- package/lib/commands/app-logs.js +54 -26
- package/lib/commands/app.js +41 -0
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +142 -68
- package/lib/commands/auth-status.js +43 -54
- package/lib/commands/channel.js +58 -0
- package/lib/commands/datasource-test-trust-cli.js +27 -23
- package/lib/commands/datasource-unified-test-cli.js +6 -3
- package/lib/commands/datasource-unified-test-cli.options.js +5 -1
- package/lib/commands/datasource.js +8 -8
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +49 -8
- package/lib/commands/identity-group-cli.js +66 -26
- package/lib/commands/identity-membership-role-cache.js +58 -37
- package/lib/commands/identity-shared.js +22 -1
- package/lib/commands/identity-user-cli.js +80 -34
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +11 -2
- package/lib/commands/repair-auth-apply.js +153 -0
- package/lib/commands/repair-auth-config.js +8 -13
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-com-v2.js +15 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-service-contract.js +206 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +49 -64
- package/lib/commands/repair-env-template.js +76 -25
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +49 -4
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +160 -0
- package/lib/commands/repair-system-alignment.js +7 -4
- package/lib/commands/repair.js +29 -296
- package/lib/commands/resource-type.js +371 -0
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +70 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +24 -8
- package/lib/commands/test-governance-external.js +3 -24
- package/lib/commands/test-trust-external.js +48 -100
- package/lib/commands/up-common.js +57 -13
- package/lib/commands/up-dataplane.js +56 -15
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +113 -110
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +73 -0
- package/lib/commands/verify-trust-external.js +59 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +2 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +90 -0
- package/lib/datasource/agent-trust-debug-log.js +1 -1
- package/lib/datasource/agent-trust-run.js +5 -3
- package/lib/datasource/audit-evidence-extract-debug.js +30 -18
- package/lib/datasource/audit-evidence-extract.js +7 -4
- package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
- package/lib/datasource/bulk-loader-run-batches.js +15 -3
- package/lib/datasource/capability/capability-diff-slice.js +2 -2
- package/lib/datasource/capability/capability-manifest.js +254 -0
- package/lib/datasource/capability/capability-resolve.js +3 -4
- package/lib/datasource/capability/copy-operations.js +5 -3
- package/lib/datasource/capability/remove-operations.js +2 -1
- package/lib/datasource/capability/run-capability-copy.js +32 -4
- package/lib/datasource/capability/run-capability-diff.js +3 -3
- package/lib/datasource/capability/run-capability-dimension.js +2 -4
- package/lib/datasource/capability/run-capability-edit.js +4 -7
- package/lib/datasource/capability/run-capability-relate.js +2 -4
- package/lib/datasource/capability/run-capability-remove.js +2 -4
- package/lib/datasource/capability/validate-capability-slice.js +2 -1
- package/lib/datasource/datasource-identifier.js +2 -1
- package/lib/datasource/datasource-load-export-context.js +3 -0
- package/lib/datasource/datasource-validate-display.js +1 -1
- package/lib/datasource/field-reference-validator.js +24 -3
- package/lib/datasource/log-cleaner.js +2 -2
- package/lib/datasource/log-viewer.js +8 -8
- package/lib/datasource/orphan-profiles-validator.js +98 -0
- package/lib/datasource/test-e2e.js +4 -1
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run.js +5 -2
- package/lib/datasource/validate.js +41 -23
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download-helpers.js +87 -0
- package/lib/external-system/download.js +78 -138
- package/lib/external-system/generator.js +1 -55
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test.js +16 -21
- package/lib/generator/builders.js +11 -1
- package/lib/generator/external-controller-manifest.js +18 -0
- package/lib/generator/split.js +3 -1
- package/lib/generator/wizard.js +1 -28
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-run-display.js +215 -25
- package/lib/identity/fk-reference.js +65 -0
- package/lib/identity/identity-apply-core.js +13 -58
- package/lib/identity/identity-apply-phases.js +5 -1
- package/lib/identity/identity-display.js +243 -0
- package/lib/identity/identity-response-helpers.js +52 -0
- package/lib/identity/identity-sync-errors.js +62 -0
- package/lib/identity/resolve-user-id.js +129 -0
- package/lib/identity/username-default.js +31 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display-trust.js +70 -0
- package/lib/lifecycle/report-display.js +472 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +10 -4
- package/lib/resolvers/datasource-resolver.js +2 -3
- package/lib/resolvers/resource-type-file.js +159 -0
- package/lib/schema/application-schema.json +17 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/deployment-rules.yaml +2 -1
- package/lib/schema/external-datasource.schema.json +2947 -2619
- package/lib/schema/external-system.schema.json +1418 -761
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/type/credential-field-registry.json +103 -97
- package/lib/schema/type/document-storage.json +9 -5
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/app-run-containers.js +25 -2
- package/lib/utils/authentication-shape.js +224 -0
- package/lib/utils/build-copy.js +36 -5
- package/lib/utils/build-resolve-image.js +66 -12
- package/lib/utils/celery-companion-apps.js +53 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-utils.js +20 -4
- package/lib/utils/compose-celery-worker.js +23 -0
- package/lib/utils/compose-generate-docker-compose.js +13 -1
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/configuration-env-resolver.js +36 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-secrets-env-kv.js +216 -0
- package/lib/utils/credential-secrets-env.js +175 -257
- package/lib/utils/dataplane-resolver.js +18 -2
- package/lib/utils/declarative-url-ports.js +27 -4
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/docker-build.js +1 -4
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +11 -3
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/external-system-validators.js +8 -2
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +13 -8
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +2 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +157 -0
- package/lib/utils/platform-kv-ref.js +57 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/runtime-configuration-download.js +189 -0
- package/lib/utils/runtime-configuration-values.js +119 -0
- package/lib/utils/schema-loader.js +19 -4
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +12 -5
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +8 -0
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/utils/worker-sidecars.js +142 -0
- package/lib/validation/external-manifest-validator.js +2 -0
- package/lib/validation/runtime-configuration-rules.js +98 -0
- package/lib/validation/validate-display-dimensions.js +154 -0
- package/lib/validation/validate-display-sections.js +276 -0
- package/lib/validation/validate-display-steps.js +67 -0
- package/lib/validation/validate-display.js +24 -402
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +7 -1
- package/templates/applications/dataplane/env.template +50 -14
- package/templates/applications/dataplane/rbac.yaml +108 -1
- package/templates/applications/miso-controller/application.yaml +2 -2
- package/templates/applications/miso-controller/env.template +53 -122
- package/templates/applications/miso-controller/rbac.yaml +28 -13
- package/templates/channels/chatgpt/install.template.md.hbs +49 -0
- package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
- package/templates/channels/slack/install.template.md.hbs +49 -0
- package/templates/channels/slack/manifest.template.json.hbs +66 -0
- package/templates/channels/teams-bot/install.template.md.hbs +49 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
- package/templates/channels/web-embed/install.template.md.hbs +49 -0
- package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
- package/templates/external-system/README.md.hbs +74 -17
- package/templates/python/docker-compose.hbs +75 -18
- package/templates/typescript/docker-compose.hbs +70 -17
- package/lib/commands/test-governance-command-action.js +0 -55
- package/lib/commands/test-trust-command-action.js +0 -118
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
const { getDeveloperIdNumber } = require('./env-map');
|
|
13
13
|
const devConfig = require('./dev-config');
|
|
14
14
|
const config = require('../core/config');
|
|
15
|
+
const { getDeviceToken, isTokenExpired } = require('./token-manager');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Calculate default controller URL based on developer ID
|
|
@@ -40,7 +41,6 @@ function normalizeUrl(url) {
|
|
|
40
41
|
}
|
|
41
42
|
return url.trim().replace(/\/+$/, '');
|
|
42
43
|
}
|
|
43
|
-
|
|
44
44
|
/**
|
|
45
45
|
* True when `config.yaml` has a non-expired-looking device entry for this controller URL
|
|
46
46
|
* (normalized host/path comparison).
|
|
@@ -68,6 +68,90 @@ async function hasStoredDeviceTokenForController(controllerUrl) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* True when a stored, non-expired device token exists (local config only — no refresh HTTP).
|
|
73
|
+
* Setup uses this to decide whether to skip the device-login step; avoids refresh warnings
|
|
74
|
+
* when the controller is not up yet or `device:` is empty.
|
|
75
|
+
*
|
|
76
|
+
* @async
|
|
77
|
+
* @param {string} controllerUrl
|
|
78
|
+
* @returns {Promise<boolean>}
|
|
79
|
+
*/
|
|
80
|
+
async function isDeviceTokenUsableForController(controllerUrl) {
|
|
81
|
+
if (!(await hasStoredDeviceTokenForController(controllerUrl))) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const want = normalizeUrl(controllerUrl);
|
|
85
|
+
try {
|
|
86
|
+
const tokenInfo = await getDeviceToken(want);
|
|
87
|
+
return Boolean(tokenInfo && tokenInfo.token && !isTokenExpired(tokenInfo.expiresAt));
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* True when a stored device token can be refreshed (if needed) and validated against the controller API.
|
|
95
|
+
* Prefer this after the controller is reachable (guided platform auth step). Falls back to local expiry-only
|
|
96
|
+
* check when the controller is not reachable yet.
|
|
97
|
+
*
|
|
98
|
+
* @async
|
|
99
|
+
* @param {string} controllerUrl
|
|
100
|
+
* @returns {Promise<boolean>}
|
|
101
|
+
*/
|
|
102
|
+
async function isPlatformAuthValidForController(controllerUrl) {
|
|
103
|
+
if (!(await hasStoredDeviceTokenForController(controllerUrl))) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const want = normalizeUrl(controllerUrl);
|
|
107
|
+
|
|
108
|
+
if (!(await isControllerHealthReachable(want))) {
|
|
109
|
+
return isDeviceTokenUsableForController(controllerUrl);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const { getOrRefreshDeviceToken } = require('./token-manager');
|
|
113
|
+
const { getAuthUser } = require('../api/auth.api');
|
|
114
|
+
|
|
115
|
+
let tokenResult = null;
|
|
116
|
+
try {
|
|
117
|
+
tokenResult = await getOrRefreshDeviceToken(want);
|
|
118
|
+
} catch {
|
|
119
|
+
tokenResult = null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!tokenResult || !tokenResult.token) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const response = await getAuthUser(want, { type: 'bearer', token: tokenResult.token });
|
|
128
|
+
return Boolean(response.success && response.data && response.data.authenticated !== false);
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Best-effort GET /health on the controller (no auth). Used to avoid token refresh HTTP
|
|
136
|
+
* during setup before Miso Controller is running.
|
|
137
|
+
*
|
|
138
|
+
* @async
|
|
139
|
+
* @param {string} controllerUrl
|
|
140
|
+
* @returns {Promise<boolean>}
|
|
141
|
+
*/
|
|
142
|
+
async function isControllerHealthReachable(controllerUrl) {
|
|
143
|
+
const base = normalizeUrl(controllerUrl);
|
|
144
|
+
if (!base) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const res = await fetch(`${base}/health`, { signal: AbortSignal.timeout(2500) });
|
|
149
|
+
return res.ok;
|
|
150
|
+
} catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
71
155
|
/**
|
|
72
156
|
* Get controller URL from logged-in user's device tokens.
|
|
73
157
|
* Prefers the entry under {@link config.controller} when it matches a `device` key; otherwise a
|
|
@@ -152,6 +236,9 @@ async function resolveControllerUrl() {
|
|
|
152
236
|
module.exports = {
|
|
153
237
|
getDefaultControllerUrl,
|
|
154
238
|
hasStoredDeviceTokenForController,
|
|
239
|
+
isDeviceTokenUsableForController,
|
|
240
|
+
isPlatformAuthValidForController,
|
|
241
|
+
isControllerHealthReachable,
|
|
155
242
|
getControllerUrlFromLoggedInUser,
|
|
156
243
|
getControllerFromConfig,
|
|
157
244
|
resolveControllerUrl
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KV_* env key ↔ kv:// path mapping and payload reference scanning.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview KV path helpers for credential-secrets-env
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const KV_PREFIX = 'KV_';
|
|
10
|
+
const KV_REF_PATTERN = /kv:\/\/([a-zA-Z0-9_\-/]+)/g;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts systemKey to KV_* prefix (e.g. hubspot -> HUBSPOT, my-hubspot -> MY_HUBSPOT).
|
|
14
|
+
* @param {string} systemKey - System key
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
function systemKeyToKvPrefix(systemKey) {
|
|
18
|
+
if (!systemKey || typeof systemKey !== 'string') return '';
|
|
19
|
+
return systemKey.replace(/-/g, '_').toUpperCase();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maps authentication security key (camelCase) to env VAR (UPPERCASE, no underscores).
|
|
24
|
+
* @param {string} securityKey - Security key (e.g. 'clientId', 'clientSecret')
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
function securityKeyToVar(securityKey) {
|
|
28
|
+
if (!securityKey || typeof securityKey !== 'string') return '';
|
|
29
|
+
return securityKey.replace(/_/g, '').toUpperCase();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Known single-segment variable suffixes (uppercase) for inferring var vs namespace in env keys */
|
|
33
|
+
const VAR_SUFFIXES = new Set(['ID', 'SECRET', 'KEY', 'TOKEN', 'URL', 'USERNAME', 'PASSWORD']);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Converts var segment(s) from env key to path-style camelCase.
|
|
37
|
+
* @param {string[]} varSegments - One or two segments (e.g. ['CLIENT', 'ID'], ['CLIENTID'])
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
function varSegmentsToCamelCase(varSegments) {
|
|
41
|
+
if (!varSegments || varSegments.length === 0) return '';
|
|
42
|
+
if (varSegments.length === 1) {
|
|
43
|
+
const s = varSegments[0].toLowerCase();
|
|
44
|
+
if (s.endsWith('id') && s.length > 2) return s.slice(0, -2) + 'Id';
|
|
45
|
+
if (s.endsWith('secret') && s.length > 6) return s.slice(0, -6) + 'Secret';
|
|
46
|
+
if (s.endsWith('key') && s.length > 3) return s.slice(0, -3) + 'Key';
|
|
47
|
+
if (s.endsWith('token') && s.length > 5) return s.slice(0, -5) + 'Token';
|
|
48
|
+
if (s.endsWith('url') && s.length > 3) return s.slice(0, -3) + 'Url';
|
|
49
|
+
return s;
|
|
50
|
+
}
|
|
51
|
+
return varSegments.map((seg, i) => {
|
|
52
|
+
const lower = seg.toLowerCase();
|
|
53
|
+
return i === 0 ? lower : lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
54
|
+
}).join('');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {string[]} segments - Parsed segments after KV_ prefix
|
|
59
|
+
* @param {string} systemKey - System key (e.g. 'microsoft-teams')
|
|
60
|
+
* @returns {string|null}
|
|
61
|
+
*/
|
|
62
|
+
function kvPathWithSystemKey(segments, systemKey) {
|
|
63
|
+
const prefixInKey = systemKey.replace(/-/g, '_').toUpperCase();
|
|
64
|
+
const prefixSegs = prefixInKey.split('_').filter(Boolean);
|
|
65
|
+
if (segments.length <= prefixSegs.length) return null;
|
|
66
|
+
const prefixMatch = prefixSegs.every((p, i) => segments[i] === p);
|
|
67
|
+
if (!prefixMatch) return null;
|
|
68
|
+
const varSegments = segments.slice(prefixSegs.length);
|
|
69
|
+
const pathVar = varSegmentsToCamelCase(varSegments);
|
|
70
|
+
return pathVar ? `kv://${systemKey}/${pathVar}` : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {string[]} segments - Parsed segments after KV_ prefix
|
|
75
|
+
* @returns {string|null}
|
|
76
|
+
*/
|
|
77
|
+
function kvPathInferred(segments) {
|
|
78
|
+
if (segments.length === 1) return `kv://${segments[0].toLowerCase()}`;
|
|
79
|
+
const varSegmentCount = (segments.length >= 2 && VAR_SUFFIXES.has(segments[segments.length - 1])) ? 2 : 1;
|
|
80
|
+
const namespace = segments.slice(0, -varSegmentCount).map(s => s.toLowerCase()).join('-');
|
|
81
|
+
const varSegments = segments.slice(-varSegmentCount);
|
|
82
|
+
const pathVar = varSegmentsToCamelCase(varSegments);
|
|
83
|
+
return (namespace && pathVar) ? `kv://${namespace}/${pathVar}` : null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {string} securityKey - Security key (e.g. 'apiKey', 'clientId')
|
|
88
|
+
* @returns {string}
|
|
89
|
+
*/
|
|
90
|
+
function getKvPathSegmentForSecurityKey(securityKey) {
|
|
91
|
+
if (!securityKey || typeof securityKey !== 'string') return '';
|
|
92
|
+
return varSegmentsToCamelCase([securityKeyToVar(securityKey)]);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {string} envKey - Env var name (e.g. KV_MICROSOFT_TEAMS_CLIENT_ID)
|
|
97
|
+
* @param {string} [systemKey] - Optional system key
|
|
98
|
+
* @returns {string|null}
|
|
99
|
+
*/
|
|
100
|
+
function kvEnvKeyToPath(envKey, systemKey) {
|
|
101
|
+
if (!envKey || typeof envKey !== 'string' || !envKey.toUpperCase().startsWith(KV_PREFIX)) return null;
|
|
102
|
+
const rest = envKey.slice(KV_PREFIX.length).trim();
|
|
103
|
+
if (!rest) return null;
|
|
104
|
+
const segments = rest.split('_').filter(Boolean);
|
|
105
|
+
if (segments.length === 0) return null;
|
|
106
|
+
|
|
107
|
+
const hasSystemKey = typeof systemKey === 'string' && systemKey.length > 0;
|
|
108
|
+
if (hasSystemKey) return kvPathWithSystemKey(segments, systemKey);
|
|
109
|
+
return kvPathInferred(segments);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @param {Object.<string, string>} envMap - Key-value map from .env
|
|
114
|
+
* @param {string} [systemKey]
|
|
115
|
+
* @returns {Array<{ key: string, value: string }>}
|
|
116
|
+
*/
|
|
117
|
+
function collectKvEnvVarsAsSecretItems(envMap, systemKey) {
|
|
118
|
+
if (!envMap || typeof envMap !== 'object') {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
const items = [];
|
|
122
|
+
for (const [envKey, rawValue] of Object.entries(envMap)) {
|
|
123
|
+
const value = typeof rawValue === 'string' ? rawValue.trim() : '';
|
|
124
|
+
if (value === '') continue;
|
|
125
|
+
let kvPath = null;
|
|
126
|
+
if (value.startsWith('kv://') && isValidKvPath(value)) {
|
|
127
|
+
kvPath = value;
|
|
128
|
+
}
|
|
129
|
+
if (!kvPath) kvPath = kvEnvKeyToPath(envKey, systemKey) || kvEnvKeyToPath(envKey);
|
|
130
|
+
if (!kvPath) continue;
|
|
131
|
+
items.push({ key: kvPath, value });
|
|
132
|
+
}
|
|
133
|
+
return items;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @param {Object} secrets - Loaded secrets object
|
|
138
|
+
* @param {string} value - Value (may be "kv://..." or plain)
|
|
139
|
+
* @returns {string|null}
|
|
140
|
+
*/
|
|
141
|
+
function resolveKvValue(secrets, value) {
|
|
142
|
+
if (typeof value !== 'string') return null;
|
|
143
|
+
const trimmed = value.trim();
|
|
144
|
+
if (!trimmed.startsWith('kv://')) {
|
|
145
|
+
return trimmed;
|
|
146
|
+
}
|
|
147
|
+
const pathMatch = trimmed.match(/^kv:\/\/([a-zA-Z0-9_\-/]+)$/);
|
|
148
|
+
if (!pathMatch) return null;
|
|
149
|
+
const pathKey = pathMatch[1];
|
|
150
|
+
const resolved = secrets[pathKey];
|
|
151
|
+
if (resolved === undefined) return null;
|
|
152
|
+
return typeof resolved === 'string' ? resolved : String(resolved);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {Object|Array|string|number|boolean|null} obj
|
|
157
|
+
* @param {Set<string>} [acc]
|
|
158
|
+
* @returns {string[]}
|
|
159
|
+
*/
|
|
160
|
+
function collectKvRefsFromPayload(obj, acc = new Set()) {
|
|
161
|
+
if (obj === null || obj === undefined) {
|
|
162
|
+
return Array.from(acc);
|
|
163
|
+
}
|
|
164
|
+
if (typeof obj === 'string') {
|
|
165
|
+
let m;
|
|
166
|
+
KV_REF_PATTERN.lastIndex = 0;
|
|
167
|
+
while ((m = KV_REF_PATTERN.exec(obj)) !== null) {
|
|
168
|
+
acc.add(`kv://${m[1]}`);
|
|
169
|
+
}
|
|
170
|
+
return Array.from(acc);
|
|
171
|
+
}
|
|
172
|
+
if (Array.isArray(obj)) {
|
|
173
|
+
for (const item of obj) {
|
|
174
|
+
collectKvRefsFromPayload(item, acc);
|
|
175
|
+
}
|
|
176
|
+
return Array.from(acc);
|
|
177
|
+
}
|
|
178
|
+
if (typeof obj === 'object') {
|
|
179
|
+
for (const v of Object.values(obj)) {
|
|
180
|
+
collectKvRefsFromPayload(v, acc);
|
|
181
|
+
}
|
|
182
|
+
return Array.from(acc);
|
|
183
|
+
}
|
|
184
|
+
return Array.from(acc);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @param {string} key - kv:// path
|
|
189
|
+
* @returns {boolean}
|
|
190
|
+
*/
|
|
191
|
+
function isValidKvPath(key) {
|
|
192
|
+
return typeof key === 'string' && /^kv:\/\/[a-z0-9][a-z0-9\-/]*$/i.test(key.trim());
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @param {unknown} resolved
|
|
197
|
+
* @returns {boolean}
|
|
198
|
+
*/
|
|
199
|
+
function isNonEmptySecretValue(resolved) {
|
|
200
|
+
if (resolved === null || resolved === undefined) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return String(resolved).trim() !== '';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
module.exports = {
|
|
207
|
+
collectKvEnvVarsAsSecretItems,
|
|
208
|
+
collectKvRefsFromPayload,
|
|
209
|
+
getKvPathSegmentForSecurityKey,
|
|
210
|
+
isNonEmptySecretValue,
|
|
211
|
+
isValidKvPath,
|
|
212
|
+
kvEnvKeyToPath,
|
|
213
|
+
resolveKvValue,
|
|
214
|
+
securityKeyToVar,
|
|
215
|
+
systemKeyToKvPrefix
|
|
216
|
+
};
|