@go-to-k/cdkd 0.284.3 → 0.284.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as IntrinsicFunctionResolver, $n as StackTerminationProtectionError, $t as buildDenyExternalAccessPolicy, A as formatResourceLine, An as processStackMessages, At as withRetry, B as isExportAliasCollision, Bt as buildAssetRedirectMap, C as refusesFinalSnapshot, Cn as findLargeInlineResources, Ct as s3BucketDualStackDomainName, D as MULTI_REGION_RECREATE_BLOCKED_TYPES, Dn as canonicalizeRegion, Dt as DiffCalculator, E as extractDeploymentEventError, En as PARTITION_TABLE, Et as applyRoleArnIfSet, F as red, Fn as resetAwsClients, Ft as rebuildClientForBucketRegion, G as clearOnUpdateRemoval, Gt as stripControlChars, H as stateKeySecretExposure, Hn as LocalInvokeBuildError$1, Ht as loadPublishableAssetManifest, I as yellow, In as setAwsClients, It as shouldRetainResource, J as findSilentDropProperties, Jn as PartialFailureError, Jt as ensureAssetStorage, K as ProviderRegistry, Kn as MissingCdkCliError, Kt as AssetModeResolver, L as collectDeclaredOutputNames, Lt as AssetPublisher, M as cyan, Mn as resolveBucketRegion, Mt as TemplateParser, N as gray, Nn as AwsClients, Nt as LockManager, O as isStatefulRecreateTargetSync, On as derivePartitionAndUrlSuffix, Ot as INTRINSIC_KEYS, P as green, Pn as getAwsClients, Pt as S3StateBackend, Q as isTerminationProtectionPropagationError, Qn as StackHasActiveImportsError, Qt as validateContainerRepoName, R as collectPublishedOutputNames, Rn as CdkdError, Rt as stringifyValue, S as isFinalSnapshotError, Sn as MIGRATE_TMP_PREFIX, St as s3BucketDomainName, T as makeCanonicalizePropertiesFn, Tn as expectedOwnerParam, Tt as s3BucketWebsiteUrl, U as IAMRoleProvider, Un as LocalMigrateError, Ut as rewriteTemplateAssetReferences, V as secretBearingStateKeyWarning, Vn as DeployCancelledError, Vt as createAssetRedirectResolver, W as collectInlinePolicyNamesManagedBySiblings, Wn as LocalStartServiceError, Wt as escapeRegExp, X as slowCcOperationTimeoutMs, Xn as ResourceTimeoutError, Xt as parseBootstrapMarker, Y as CloudControlProvider, Yn as ProvisioningError, Yt as getBootstrapMarkerKey, Z as disableInstanceApiTermination, Zn as ResourceUpdateNotSupportedError, Zt as validateAssetBucketName, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _n as resolveUseCdkBootstrapAssets, _t as TEMPLATE_SOURCED_RULES, a as DeploymentEventsStore, an as AssetManifestLoader, ar as withErrorHandling, at as resolveExplicitPhysicalId, b as ccRoutedFinalSnapshotError, bn as CFN_TEMPLATE_BODY_LIMIT, bt as scrubResourceRecord, c as replayFailedOperations, cn as synthesisStatusMessage, cr as isThrottlingError, ct as configBooleanRefusal, d as updatePartialReason, dn as resolveApp, dt as replayWarn, en as buildDockerImage, et as cfnRefValueFromPhysicalId, f as UNSPECIFIED_SKIP_REASON, fn as resolveAutoAssetStorage, ft as requireConfigArray, g as computeImplicitDeleteEdges, gn as resolveStateBucketWithDefaultAndSource, gt as STATE_SOURCED_READBACK_RULES, h as IMPLICIT_DELETE_DEPENDENCIES, hn as resolveStateBucketWithDefault, ht as STATE_SOURCED_CROSS_GENERATION_RULES, i as DeploymentEventsReader, in as runDockerStreaming, ir as normalizeAwsError, it as normalizeAwsTagsToCfn, j as bold, jt as DagBuilder, k as renderStatefulReason, kn as AssemblyReader, kt as describeTypeWithThrottleRetry, l as replayRollback, ln as getDefaultStateBucketName, lr as markNonRetryable, lt as configStringRefusal, m as withResourceDeadline, mn as resolveSkipPrefix, mt as requireConfigString, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as getDockerCmd, nt as refStateLookupFromResource, o as planFailedOps, on as getDockerImageBySourceHash, or as isMarkedNonRetryable, ot as assertRegionMatch, p as deleteSkipReason, pn as resolveCaptureObservedState, pt as requireConfigObject, q as findActionableSilentDrops, qn as NestedStackChildDirectDestroyError, qt as BOOTSTRAP_MARKER_PREFIX, r as DeployEngine, rn as runDockerForeground, rt as WAFv2WebACLProvider, s as planRollback, sn as Synthesizer, sr as isRetryableTransientError, st as coerceCfnBoolean, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as formatDockerLoginError, tt as getAccountInfo, u as updatePartialMessage, un as getLegacyStateBucketName, ut as readConfigString, v as PRE_DELETE_SNAPSHOT_TYPES, vn as stateBucketExistenceConfirmed, vt as maskSecretsInText, w as unsupportedFinalSnapshotError, wn as uploadCfnTemplate, wt as s3BucketRegionalDomainName, x as createPreDeleteFinalSnapshot, xn as CFN_TEMPLATE_URL_LIMIT, xt as s3BucketArn, y as buildFinalSnapshotIdentifier, yn as warnDeprecatedNoPrefixCliFlag, yt as redactSecretsForState, z as exportAliasCollisionScrubWarning, zt as WorkGraph } from "./deploy-engine-DJ-CgH80.js";
2
+ import { $ as IntrinsicFunctionResolver, $n as StackHasActiveImportsError, $t as validateContainerRepoName, A as formatResourceLine, An as AssemblyReader, At as describeTypeWithThrottleRetry, B as isExportAliasCollision, Bt as WorkGraph, C as refusesFinalSnapshot, Cn as MIGRATE_TMP_PREFIX, Ct as s3BucketDomainName, D as MULTI_REGION_RECREATE_BLOCKED_TYPES, Dn as PARTITION_TABLE, Dt as applyRoleArnIfSet, E as extractDeploymentEventError, En as expectedOwnerParam, Et as s3BucketWebsiteUrl, F as red, Fn as getAwsClients, Ft as S3StateBackend, G as clearOnUpdateRemoval, Gn as LocalStartServiceError, Gt as escapeRegExp, H as stateKeySecretExposure, Hn as DeployCancelledError, Ht as createAssetRedirectResolver, I as yellow, In as resetAwsClients, It as rebuildClientForBucketRegion, J as findSilentDropProperties, Jn as NestedStackChildDirectDestroyError, Jt as BOOTSTRAP_MARKER_PREFIX, K as ProviderRegistry, Kt as stripControlChars, L as collectDeclaredOutputNames, Ln as setAwsClients, Lt as shouldRetainResource, M as cyan, Mt as DagBuilder, N as gray, Nn as resolveBucketRegion, Nt as TemplateParser, O as isStatefulRecreateTargetSync, On as canonicalizeRegion, Ot as DiffCalculator, P as green, Pn as AwsClients, Pt as LockManager, Q as isTerminationProtectionPropagationError, Qn as ResourceUpdateNotSupportedError, Qt as validateAssetBucketName, R as collectPublishedOutputNames, Rt as AssetPublisher, S as isFinalSnapshotError, Sn as CFN_TEMPLATE_URL_LIMIT, St as s3BucketArn, T as makeCanonicalizePropertiesFn, Tn as uploadCfnTemplate, Tt as s3BucketRegionalDomainName, U as IAMRoleProvider, Un as LocalInvokeBuildError$1, Ut as loadPublishableAssetManifest, V as secretBearingStateKeyWarning, Vt as buildAssetRedirectMap, W as collectInlinePolicyNamesManagedBySiblings, Wn as LocalMigrateError, Wt as rewriteTemplateAssetReferences, X as slowCcOperationTimeoutMs, Xn as ProvisioningError, Xt as getBootstrapMarkerKey, Y as CloudControlProvider, Yn as PartialFailureError, Yt as ensureAssetStorage, Z as disableInstanceApiTermination, Zn as ResourceTimeoutError, Zt as parseBootstrapMarker, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _n as resolveStateBucketWithDefaultAndSource, _t as TEMPLATE_SOURCED_RULES, a as DeploymentEventsStore, an as runDockerStreaming, ar as normalizeAwsError, at as resolveExplicitPhysicalId, b as ccRoutedFinalSnapshotError, bn as warnDeprecatedNoPrefixCliFlag, bt as redactSecretsForState, c as replayFailedOperations, cn as Synthesizer, cr as isRetryableTransientError, ct as configBooleanRefusal, d as updatePartialReason, dn as getLegacyStateBucketName, dt as replayWarn, en as buildDenyExternalAccessPolicy, er as StackTerminationProtectionError, et as cfnRefValueFromPhysicalId, f as UNSPECIFIED_SKIP_REASON, fn as resolveApp, ft as requireConfigArray, g as computeImplicitDeleteEdges, gn as resolveStateBucketWithDefault, gt as STATE_SOURCED_READBACK_RULES, h as IMPLICIT_DELETE_DEPENDENCIES, hn as resolveSkipPrefix, ht as STATE_SOURCED_CROSS_GENERATION_RULES, i as DeploymentEventsReader, in as runDockerForeground, it as normalizeAwsTagsToCfn, j as bold, jn as processStackMessages, jt as withRetry, k as renderStatefulReason, kn as derivePartitionAndUrlSuffix, kt as INTRINSIC_KEYS, l as replayRollback, ln as synthesisStatusMessage, lr as isThrottlingError, lt as configStringRefusal, m as withResourceDeadline, mn as resolveCaptureObservedState, mt as requireConfigString, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as formatDockerLoginError, nt as refStateLookupFromResource, o as planFailedOps, on as AssetManifestLoader, or as withErrorHandling, ot as assertRegionMatch, p as deleteSkipReason, pn as resolveAutoAssetStorage, pt as requireConfigObject, q as findActionableSilentDrops, qn as MissingCdkCliError, qt as AssetModeResolver, r as DeployEngine, rn as getDockerCmd, rt as WAFv2WebACLProvider, s as planRollback, sn as getDockerImageBySourceHash, sr as isMarkedNonRetryable, st as coerceCfnBoolean, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as buildDockerImage, tt as getAccountInfo, u as updatePartialMessage, un as getDefaultStateBucketName, ur as markNonRetryable, ut as readConfigString, v as PRE_DELETE_SNAPSHOT_TYPES, vn as resolveUseCdkBootstrapAssets, vt as createSecretMasker, w as unsupportedFinalSnapshotError, wn as findLargeInlineResources, wt as s3BucketDualStackDomainName, x as createPreDeleteFinalSnapshot, xn as CFN_TEMPLATE_BODY_LIMIT, xt as scrubResourceRecord, y as buildFinalSnapshotIdentifier, yn as stateBucketExistenceConfirmed, yt as maskSecretsInText, z as exportAliasCollisionScrubWarning, zn as CdkdError, zt as stringifyValue } from "./deploy-engine-BKSfYWps.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
4
- import { t as ASGProvider } from "./asg-provider-iHWEv4gN.js";
4
+ import { t as ASGProvider } from "./asg-provider-C1NtROYt.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -39659,6 +39659,15 @@ function readDeclaredMfaConfiguration(raw, options) {
39659
39659
  return value.trim() === "" ? "" : value;
39660
39660
  }
39661
39661
  /**
39662
+ * Depth cap for the pre-stringify secret walk in {@link buildMfaConfigRequest}.
39663
+ *
39664
+ * Only a guard against a self-referential bag, not a real bound: a resolved
39665
+ * `EnabledMfas` is a list of factor-name scalars, so the walk never reaches
39666
+ * depth 2 on any shape this warning exists to describe. Deliberately generous
39667
+ * so no plausible mis-shape is left unmasked by it.
39668
+ */
39669
+ const MASK_WALK_MAX_DEPTH = 8;
39670
+ /**
39662
39671
  * Read `EnabledMfas` as the pair (recognized list, "the template asked for a
39663
39672
  * factor at all").
39664
39673
  *
@@ -39745,9 +39754,31 @@ function hasMfaConfigProps(properties) {
39745
39754
  * is also needed for the `CreateUserPool` / `UpdateUserPool` forward — and so
39746
39755
  * the create path can REFUSE a malformed value while the update path only
39747
39756
  * warns, which is the split `requireConfigString`'s `onUnusable` encodes.
39748
- */
39749
- function buildMfaConfigRequest(physicalId, properties, logger, declaredMfaConfiguration = "") {
39757
+ *
39758
+ * `maskSecrets` is the caller's secret masker (issue #1932 item 3), threaded
39759
+ * from `CreateContext` / `UpdateContext` — see `SecretMaskingContext` in
39760
+ * `src/types/resource.ts`. Every warning below is routed through it because
39761
+ * they name RESOLVED property values: by the time a provider is called a
39762
+ * `{{resolve:secretsmanager:...}}` scalar is already plaintext, and cdkd's
39763
+ * other two masking boundaries (the deploy engine's error/reason text and the
39764
+ * resolver's debug line) do not cover a provider's own `logger.warn`.
39765
+ *
39766
+ * Typed as the contract's own `SecretMasker`, imported from
39767
+ * `src/types/resource.ts` (which re-exports it for exactly this reason, the
39768
+ * same way it re-exports `DeleteContext`). An earlier draft re-declared it
39769
+ * structurally as `(text: string) => string` on a layering argument — keeping
39770
+ * `src/provisioning/**` clear of `src/deployment/secret-redaction.ts` — but
39771
+ * `types/resource.ts` already crosses that boundary with a type-only import,
39772
+ * so the re-declaration bought nothing and left the provider's parameter type
39773
+ * free to drift from the contract. The layering argument survives where it is
39774
+ * still true: providers import from `types/resource.ts`, never from the
39775
+ * deployment module, and never the secrets BAG. It defaults to IDENTITY so the
39776
+ * diff-side caller (`resolveSentMfaConfiguration`) and every unit test keep
39777
+ * working unchanged.
39778
+ */
39779
+ function buildMfaConfigRequest(physicalId, properties, logger, declaredMfaConfiguration = "", maskSecrets = (text) => text) {
39750
39780
  const { factors: enabledMfas, declaresFactor, malformed: enabledMfasMalformed, blank: enabledMfasBlank } = readEnabledMfas(properties);
39781
+ const warn = (message) => logger?.warn(maskSecrets(message));
39751
39782
  const emailMessage = properties["EmailAuthenticationMessage"] || void 0;
39752
39783
  const emailSubject = properties["EmailAuthenticationSubject"] || void 0;
39753
39784
  const webAuthnRpId = properties["WebAuthnRelyingPartyID"] || void 0;
@@ -39768,14 +39799,21 @@ function buildMfaConfigRequest(physicalId, properties, logger, declaredMfaConfig
39768
39799
  };
39769
39800
  const enablesMfaFactor = declaresFactor || request.EmailMfaConfiguration !== void 0;
39770
39801
  request.MfaConfiguration = declaredMfaConfiguration || (enablesMfaFactor ? "OPTIONAL" : "OFF");
39771
- if (enabledMfasBlank) logger?.warn(`UserPool ${physicalId}: EnabledMfas is an empty string, which declares no MFA factor and is treated as absent — a mangled Fn::Join or an empty String parameter collapses to this shape. Nothing is enabled from it and MfaConfiguration is ${request.MfaConfiguration}; declare the factor names as a list (e.g. ["${MFA_FACTOR_SOFTWARE_TOKEN}"]) if a factor was intended.`);
39802
+ if (enabledMfasBlank) warn(`UserPool ${physicalId}: EnabledMfas is an empty string, which declares no MFA factor and is treated as absent — a mangled Fn::Join or an empty String parameter collapses to this shape. Nothing is enabled from it and MfaConfiguration is ${request.MfaConfiguration}; declare the factor names as a list (e.g. ["${MFA_FACTOR_SOFTWARE_TOKEN}"]) if a factor was intended.`);
39772
39803
  const anyFactorBlock = request.SmsMfaConfiguration !== void 0 || request.SoftwareTokenMfaConfiguration !== void 0 || request.EmailMfaConfiguration !== void 0;
39773
- if (request.MfaConfiguration === "OFF" && anyFactorBlock) logger?.warn(`UserPool ${physicalId}: MfaConfiguration is pinned to OFF while an MFA factor block is configured. AWS REJECTS that combination ("Invalid MFA configuration given, can't turn off MFA and configure an MFA together"), so this deploy FAILS rather than producing a pool with MFA disabled. Remove MfaConfiguration (or set it to ON / OPTIONAL) to enable the declared factor.`);
39774
- const dropped = unrecognizedFactors.map((f) => JSON.stringify(f) ?? String(f));
39775
- if (enabledMfasMalformed) dropped.push(`${JSON.stringify(properties["EnabledMfas"])} (not a list)`);
39804
+ if (request.MfaConfiguration === "OFF" && anyFactorBlock) warn(`UserPool ${physicalId}: MfaConfiguration is pinned to OFF while an MFA factor block is configured. AWS REJECTS that combination ("Invalid MFA configuration given, can't turn off MFA and configure an MFA together"), so this deploy FAILS rather than producing a pool with MFA disabled. Remove MfaConfiguration (or set it to ON / OPTIONAL) to enable the declared factor.`);
39805
+ const maskDeep = (v, depth = 0) => {
39806
+ if (typeof v === "string") return maskSecrets(v);
39807
+ if (depth >= MASK_WALK_MAX_DEPTH) return v;
39808
+ if (Array.isArray(v)) return v.map((e) => maskDeep(e, depth + 1));
39809
+ if (v !== null && typeof v === "object") return Object.fromEntries(Object.entries(v).map(([k, x]) => [maskSecrets(k), maskDeep(x, depth + 1)]));
39810
+ return v;
39811
+ };
39812
+ const dropped = unrecognizedFactors.map((f) => JSON.stringify(maskDeep(f)) ?? String(f));
39813
+ if (enabledMfasMalformed) dropped.push(`${JSON.stringify(maskDeep(properties["EnabledMfas"]))} (not a list)`);
39776
39814
  if (dropped.length > 0) {
39777
39815
  const consequence = request.MfaConfiguration === "OFF" && anyFactorBlock ? "MfaConfiguration is OFF while another factor block IS sent, so AWS REJECTS this call outright and the deploy fails" : request.MfaConfiguration === "OFF" ? `MfaConfiguration is OFF, so this pool deploys with MFA DISABLED` : anyFactorBlock ? `MfaConfiguration is ${request.MfaConfiguration} and another factor block IS sent, so these entries are silently ignored rather than failing the call on their own` : `MfaConfiguration is ${request.MfaConfiguration} with no factor enabled, so AWS rejects this call rather than deploying the pool with MFA disabled`;
39778
- logger?.warn(`UserPool ${physicalId}: EnabledMfas entries ${dropped.join(", ")} do not map to an MFA factor block (known: ${MFA_FACTOR_SMS}, ${MFA_FACTOR_SOFTWARE_TOKEN}, ${MFA_FACTOR_EMAIL_OTP}); no factor is enabled from them. ${consequence}.`);
39816
+ warn(`UserPool ${physicalId}: EnabledMfas entries ${dropped.join(", ")} do not map to an MFA factor block (known: ${MFA_FACTOR_SMS}, ${MFA_FACTOR_SOFTWARE_TOKEN}, ${MFA_FACTOR_EMAIL_OTP}); no factor is enabled from them. ${consequence}.`);
39779
39817
  }
39780
39818
  return request;
39781
39819
  }
@@ -40042,7 +40080,7 @@ var CognitoUserPoolProvider = class {
40042
40080
  const { urlSuffix } = derivePartitionAndUrlSuffix(region);
40043
40081
  const providerName = `cognito-idp.${region}.${urlSuffix}/${userPoolId}`;
40044
40082
  const providerUrl = `https://cognito-idp.${region}.${urlSuffix}/${userPoolId}`;
40045
- await this.applyMfaConfig(userPoolId, properties, mfaConfiguration);
40083
+ await this.applyMfaConfig(userPoolId, properties, mfaConfiguration, { ...context?.maskSecrets && { maskSecrets: context.maskSecrets } });
40046
40084
  this.logger.debug(`Successfully created Cognito User Pool ${logicalId}: ${userPoolId}`);
40047
40085
  const effectiveProperties = narrowMfaConfiguration(properties);
40048
40086
  return {
@@ -40072,9 +40110,16 @@ var CognitoUserPoolProvider = class {
40072
40110
  * present. Wrapped in a transient-error retry because back-to-back
40073
40111
  * control-plane writes on a freshly-created pool can briefly conflict
40074
40112
  * (mirrors DynamoDBTableProvider.retryOnTransientControlPlane).
40113
+ *
40114
+ * `options.maskSecrets` is the caller's secret masker (issue #1932 item 3),
40115
+ * forwarded straight to {@link buildMfaConfigRequest} where every warning is
40116
+ * routed through it. Both `create()` and `update()` supply it from their own
40117
+ * context, so the two paths cannot diverge on whether a resolved value is
40118
+ * masked. Absent (an older caller, a test, a provider invoked directly) means
40119
+ * unmasked, exactly as before.
40075
40120
  */
40076
40121
  async applyMfaConfig(physicalId, properties, declaredMfaConfiguration, options = {}) {
40077
- const request = buildMfaConfigRequest(physicalId, properties, this.logger, declaredMfaConfiguration);
40122
+ const request = buildMfaConfigRequest(physicalId, properties, this.logger, declaredMfaConfiguration, options.maskSecrets ?? ((text) => text));
40078
40123
  if (!request) return;
40079
40124
  await this.retryOnTransientControlPlane(() => this.getClient().send(new SetUserPoolMfaConfigCommand(request)), `SetUserPoolMfaConfig(${physicalId})`);
40080
40125
  this.reportMfaConfigurationOff(physicalId, request, declaredMfaConfiguration, options);
@@ -40229,8 +40274,18 @@ var CognitoUserPoolProvider = class {
40229
40274
  * ADDING new custom attributes in place via AddCustomAttributes, but cannot
40230
40275
  * modify or remove an existing attribute — those changes require replacement
40231
40276
  * and are rejected with ResourceUpdateNotSupportedError.
40277
+ *
40278
+ * The `context` parameter is read for ONE thing today: `maskSecrets` (issue
40279
+ * #1932 item 3), forwarded to `applyMfaConfig` so the MFA warnings mask a
40280
+ * resolved secret the same way they do on the create path. It deliberately
40281
+ * does NOT consult `desiredFromAwsReadback` -- this provider has no
40282
+ * empty-collection-means-delete shape, so reading that flag would be a
40283
+ * behavior change with no motivating case, and the `MfaConfiguration`
40284
+ * refusal below stays UNCONDITIONALLY downgraded for the reason its own
40285
+ * comment gives (a refusal against a state-borne bag leaves the resource
40286
+ * un-rollbackable). Accepting the context does not change that.
40232
40287
  */
40233
- async update(logicalId, physicalId, resourceType, properties, previousProperties) {
40288
+ async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
40234
40289
  this.logger.debug(`Updating Cognito User Pool ${logicalId}: ${physicalId}`);
40235
40290
  const mfaConfiguration = readDeclaredMfaConfiguration(properties["MfaConfiguration"], { onUnusable: (message) => this.logger.warn(message) });
40236
40291
  this.warnOnBlankMfaConfiguration(properties["MfaConfiguration"]);
@@ -40264,7 +40319,8 @@ var CognitoUserPoolProvider = class {
40264
40319
  await this.applyMfaConfig(physicalId, properties, mfaConfiguration, {
40265
40320
  ...liveMfa?.value !== void 0 ? { liveMfaConfiguration: liveMfa.value } : {},
40266
40321
  ...liveMfa?.failed === true ? { liveReadFailed: true } : {},
40267
- declaredKind: classifyDeclaredMfaConfiguration(properties["MfaConfiguration"])
40322
+ declaredKind: classifyDeclaredMfaConfiguration(properties["MfaConfiguration"]),
40323
+ ...context?.maskSecrets && { maskSecrets: context.maskSecrets }
40268
40324
  });
40269
40325
  this.logger.debug(`Successfully updated Cognito User Pool ${logicalId}`);
40270
40326
  const userPool = (await this.getClient().send(new DescribeUserPoolCommand({ UserPoolId: physicalId }))).UserPool;
@@ -63019,7 +63075,10 @@ async function runRevert(reports, providerRegistry, stateBackend, stateConfig, a
63019
63075
  return;
63020
63076
  }
63021
63077
  try {
63022
- const updateResult = await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties, { desiredFromAwsReadback: true }), outcome.logicalId, { logger: { debug: (msg) => logger.debug(maskSecretsInText(msg, secrets)) } });
63078
+ const updateResult = await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties, {
63079
+ desiredFromAwsReadback: true,
63080
+ maskSecrets: createSecretMasker(secrets)
63081
+ }), outcome.logicalId, { logger: { debug: (msg) => logger.debug(maskSecretsInText(msg, secrets)) } });
63023
63082
  totalSucceeded++;
63024
63083
  const revertPartial = updatePartialReason(updateResult);
63025
63084
  if (revertPartial !== void 0) logger.warn(` ✓ ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted, ${maskSecretsInText(updatePartialMessage(revertPartial), secrets)}`);
@@ -82055,7 +82114,7 @@ function createMigrateCommand() {
82055
82114
  */
82056
82115
  function buildProgram() {
82057
82116
  const program = new Command();
82058
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.3");
82117
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.5");
82059
82118
  program.hook("preAction", (_thisCommand, actionCommand) => {
82060
82119
  const { profile } = actionCommand.optsWithGlobals();
82061
82120
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;