@kensio/yulin 1.21.34 → 1.23.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.
Files changed (76) hide show
  1. package/dist/serve/controller/sim-service-controller.d.ts +6 -0
  2. package/dist/serve/controller/sim-service-controller.js +7 -0
  3. package/dist/serve/http/request/sim-aws-request-authenticator.js +3 -0
  4. package/dist/service/apigateway/serve/sim-api-gateway-controller.js +1 -0
  5. package/dist/service/apigateway/serve/sim-rest-api-web-acl-inspection.d.ts +2 -0
  6. package/dist/service/apigateway/serve/sim-rest-api-web-acl-inspection.js +1 -0
  7. package/dist/service/cloudformation/registry/sim-cfn-attribute-reads.d.ts +11 -0
  8. package/dist/service/cloudformation/registry/sim-cfn-attribute-reads.js +64 -0
  9. package/dist/service/cloudformation/registry/sim-cfn-read-handler-authorizer.d.ts +45 -0
  10. package/dist/service/cloudformation/registry/sim-cfn-read-handler-authorizer.js +72 -0
  11. package/dist/service/cloudformation/registry/sim-cfn-read-handler.d.ts +33 -0
  12. package/dist/service/cloudformation/registry/sim-cfn-read-handler.fixture.d.ts +24 -0
  13. package/dist/service/cloudformation/registry/sim-cfn-read-handler.fixture.js +58 -0
  14. package/dist/service/cloudformation/registry/sim-cfn-read-handler.js +36 -0
  15. package/dist/service/cloudformation/registry/sim-cfn-read-handlers.d.ts +10 -0
  16. package/dist/service/cloudformation/registry/sim-cfn-read-handlers.js +23 -0
  17. package/dist/service/cloudformation/registry/sim-cfn-read-handlers.json +7400 -0
  18. package/dist/service/cloudformation/registry/sim-cfn-resource-arn.d.ts +46 -0
  19. package/dist/service/cloudformation/registry/sim-cfn-resource-arn.js +119 -0
  20. package/dist/service/cloudformation/stack/sim-cfn-stack-deploy-context.d.ts +6 -1
  21. package/dist/service/cloudformation/stack/sim-cfn-stack-deploy-context.js +3 -0
  22. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.d.ts +3 -2
  23. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.js +2 -1
  24. package/dist/service/cloudformation/stack/sim-cfn-stack.js +9 -0
  25. package/dist/service/cloudformation/stack/update/sim-cfn-stack-update-plan.d.ts +11 -0
  26. package/dist/service/cloudformation/stack/update/sim-cfn-stack-update-plan.js +22 -0
  27. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.d.ts +3 -1
  28. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.js +2 -1
  29. package/dist/service/cognito/serve/sim-cognito-controller.js +4 -3
  30. package/dist/service/cognito/serve/sim-cognito-domain-controller.js +2 -0
  31. package/dist/service/cognito/serve/sim-cognito-web-acl-inspection.d.ts +2 -0
  32. package/dist/service/cognito/serve/sim-cognito-web-acl-inspection.js +1 -0
  33. package/dist/service/iam/index.d.ts +1 -0
  34. package/dist/service/iam/index.js +1 -0
  35. package/dist/service/iam/request/error/sim-aws-request-auth.error.d.ts +1 -1
  36. package/dist/service/iam/request/error/sim-aws-request-auth.error.js +1 -1
  37. package/dist/service/iam/request/sim-aws-control-headers.d.ts +2 -1
  38. package/dist/service/iam/request/sim-aws-control-headers.js +4 -1
  39. package/dist/service/iam/request/sim-aws-source-ip-header.d.ts +19 -0
  40. package/dist/service/iam/request/sim-aws-source-ip-header.js +32 -0
  41. package/dist/service/stepfunctions/command/execution/sim-states-execution-start.js +1 -0
  42. package/dist/service/stepfunctions/execution/sim-states-run-task.js +1 -0
  43. package/dist/service/stepfunctions/execution/sim-states-state-outcome.d.ts +1 -0
  44. package/dist/service/stepfunctions/execution/sim-states-walks.d.ts +1 -0
  45. package/dist/service/stepfunctions/execution/sim-states-walks.js +1 -0
  46. package/dist/service/stepfunctions/task/sim-aws-states-task-targets.js +6 -1
  47. package/dist/service/stepfunctions/task/sim-states-execution-role.d.ts +2 -1
  48. package/dist/service/stepfunctions/task/sim-states-execution-role.js +2 -1
  49. package/dist/service/stepfunctions/task/sim-states-task-invocation.d.ts +1 -0
  50. package/dist/service/wafv2/association/sim-waf-associations.js +1 -1
  51. package/dist/service/wafv2/association/sim-waf-protection.d.ts +5 -0
  52. package/dist/service/wafv2/association/sim-waf-request-inspection.d.ts +2 -0
  53. package/dist/service/wafv2/association/sim-waf-request-inspection.js +7 -2
  54. package/dist/service/wafv2/evaluate/sim-waf-evaluation-request.d.ts +5 -0
  55. package/dist/service/wafv2/evaluate/sim-waf-inspected-request.d.ts +12 -1
  56. package/dist/service/wafv2/evaluate/sim-waf-inspected-request.js +12 -1
  57. package/dist/service/wafv2/index.d.ts +2 -1
  58. package/dist/service/wafv2/index.js +1 -0
  59. package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.d.ts +8 -5
  60. package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.js +10 -5
  61. package/dist/service/wafv2/managed/sim-waf-managed-address-declaration.d.ts +32 -0
  62. package/dist/service/wafv2/managed/sim-waf-managed-address-declaration.js +52 -0
  63. package/dist/service/wafv2/managed/sim-waf-managed-address-range.d.ts +21 -0
  64. package/dist/service/wafv2/managed/sim-waf-managed-address-range.js +73 -0
  65. package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.d.ts +7 -0
  66. package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.js +15 -0
  67. package/dist/service/wafv2/managed/sim-waf-managed-rule.type.d.ts +5 -0
  68. package/dist/service/wafv2/managed/sim-waf-managed-rules.d.ts +27 -1
  69. package/dist/service/wafv2/managed/sim-waf-managed-rules.js +33 -13
  70. package/dist/service/wafv2/sim-wafv2.js +2 -1
  71. package/dist/service/wafv2/statement/sim-waf-rate-based-input.d.ts +5 -4
  72. package/dist/service/wafv2/statement/sim-waf-rate-based-input.js +6 -6
  73. package/docs/services/cloudformation/README.md +106 -0
  74. package/docs/services/iam/README.md +6 -0
  75. package/docs/services/wafv2/README.md +105 -14
  76. package/package.json +5 -4
@@ -0,0 +1,46 @@
1
+ import type { SimCfnResource } from "../resource/sim-cfn-resource.js";
2
+ import type { SimCfnTemplateValueRecord } from "../template/value/sim-cfn-template-value.js";
3
+ interface SimCfnResourceArnProperties {
4
+ readonly resource: SimCfnResource;
5
+ readonly arnFormat: string;
6
+ readonly resolvedProperties: SimCfnTemplateValueRecord;
7
+ }
8
+ /**
9
+ * The ARN a read handler's calls on one Resource are authorized on.
10
+ *
11
+ * The ARN format's variables are filled from the Stack's scope and from the
12
+ * Resource's own properties, which is the whole of it for a Resource whose
13
+ * template names it (`DomainName` and `RepositoryName` on a CodeArtifact
14
+ * repository). A Resource whose name CloudFormation generated holds no such
15
+ * property. Its ARN comes from its `Arn` attribute, from a Ref that is an ARN, or
16
+ * from its Ref where the format has one variable left, all of which a service answers once it has
17
+ * created the Resource.
18
+ *
19
+ * An ARN that cannot be built is refused. Authorizing the calls on a guessed
20
+ * ARN would let a policy scoped to the real one pass or fail by accident.
21
+ */
22
+ export declare class SimCfnResourceArn {
23
+ private readonly resource;
24
+ private readonly arnFormat;
25
+ private readonly resolvedProperties;
26
+ constructor(properties: SimCfnResourceArnProperties);
27
+ /** The Resource's ARN, or a refusal saying which variable could not be filled. */
28
+ value(): string;
29
+ private filled;
30
+ private unfilledVariables;
31
+ private variable;
32
+ private property;
33
+ /**
34
+ * The property an ARN variable is held in under another name. The Service
35
+ * Authorization Reference names a CodeBuild project's `${ProjectName}`,
36
+ * which `AWS::CodeBuild::Project` calls `Name`.
37
+ */
38
+ private namePropertyFor;
39
+ /**
40
+ * A value the Resource answers once a service has created it. A Resource
41
+ * that was skipped answers with a stand-in naming itself, which is no part
42
+ * of an ARN.
43
+ */
44
+ private deployedValue;
45
+ }
46
+ export {};
@@ -0,0 +1,119 @@
1
+ const variablePattern = /\$\{(?<name>[^}]+)\}/gu;
2
+ /**
3
+ * The ARN a read handler's calls on one Resource are authorized on.
4
+ *
5
+ * The ARN format's variables are filled from the Stack's scope and from the
6
+ * Resource's own properties, which is the whole of it for a Resource whose
7
+ * template names it (`DomainName` and `RepositoryName` on a CodeArtifact
8
+ * repository). A Resource whose name CloudFormation generated holds no such
9
+ * property. Its ARN comes from its `Arn` attribute, from a Ref that is an ARN, or
10
+ * from its Ref where the format has one variable left, all of which a service answers once it has
11
+ * created the Resource.
12
+ *
13
+ * An ARN that cannot be built is refused. Authorizing the calls on a guessed
14
+ * ARN would let a policy scoped to the real one pass or fail by accident.
15
+ */
16
+ export class SimCfnResourceArn {
17
+ resource;
18
+ arnFormat;
19
+ resolvedProperties;
20
+ constructor(properties) {
21
+ this.resource = properties.resource;
22
+ this.arnFormat = properties.arnFormat;
23
+ this.resolvedProperties = new Map(Object.entries(properties.resolvedProperties));
24
+ }
25
+ /** The Resource's ARN, or a refusal saying which variable could not be filled. */
26
+ value() {
27
+ const unfilled = this.unfilledVariables();
28
+ if (unfilled.length === 0) {
29
+ return this.filled();
30
+ }
31
+ const arnAttribute = this.deployedValue(() => {
32
+ return this.resource.attributeValue("Arn");
33
+ });
34
+ if (arnAttribute?.startsWith("arn:") === true) {
35
+ return arnAttribute;
36
+ }
37
+ const refValue = this.deployedValue(() => this.resource.refValue);
38
+ // An SNS topic's Ref is its whole ARN, where a hosted zone's is the one
39
+ // identifier its ARN format lacks.
40
+ if (refValue?.startsWith("arn:") === true) {
41
+ return refValue;
42
+ }
43
+ const [onlyUnfilled] = unfilled;
44
+ if (refValue !== undefined && unfilled.length === 1) {
45
+ return this.filled(new Map([[onlyUnfilled, refValue]]));
46
+ }
47
+ throw new Error(`Sim CloudFormation cannot authorize the read handler of Resource ${this.resource.logicalId} (${String(this.resource.type)}): its ARN format ${this.arnFormat} needs ${unfilled.join(", ")}, which neither its properties nor its attributes give`);
48
+ }
49
+ filled(extra = new Map()) {
50
+ return this.arnFormat.replaceAll(variablePattern, (_match, name) => {
51
+ return extra.get(name) ?? this.variable(name) ?? "";
52
+ });
53
+ }
54
+ unfilledVariables() {
55
+ return this.arnFormat
56
+ .matchAll(variablePattern)
57
+ .map((match) => match.groups?.["name"] ?? "")
58
+ .filter((name) => this.variable(name) === undefined)
59
+ .toArray();
60
+ }
61
+ variable(name) {
62
+ const { accountId, regionName } = this.resource.accountRegionScope;
63
+ switch (name) {
64
+ case "Partition": {
65
+ return "aws";
66
+ }
67
+ case "Region": {
68
+ return regionName;
69
+ }
70
+ case "Account": {
71
+ return accountId;
72
+ }
73
+ default: {
74
+ return this.property(name) ?? this.property(this.namePropertyFor(name));
75
+ }
76
+ }
77
+ }
78
+ property(name) {
79
+ return stringValue(this.resolvedProperties.get(name));
80
+ }
81
+ /**
82
+ * The property an ARN variable is held in under another name. The Service
83
+ * Authorization Reference names a CodeBuild project's `${ProjectName}`,
84
+ * which `AWS::CodeBuild::Project` calls `Name`.
85
+ */
86
+ namePropertyFor(variable) {
87
+ const typeName = this.resource.type?.split("::").at(-1);
88
+ if (variable === `${String(typeName)}Name`) {
89
+ return "Name";
90
+ }
91
+ return variable;
92
+ }
93
+ /**
94
+ * A value the Resource answers once a service has created it. A Resource
95
+ * that was skipped answers with a stand-in naming itself, which is no part
96
+ * of an ARN.
97
+ */
98
+ deployedValue(read) {
99
+ const { createComplete, skipped, inert } = this.resource;
100
+ if (!createComplete || skipped || inert) {
101
+ return undefined;
102
+ }
103
+ // A Resource type with no Arn attribute refuses to answer for one, which
104
+ // here only means the ARN has to come from somewhere else.
105
+ try {
106
+ return stringValue(read());
107
+ }
108
+ catch {
109
+ return undefined;
110
+ }
111
+ }
112
+ }
113
+ /** The value where it is a string, which is all an ARN can be made of. */
114
+ function stringValue(value) {
115
+ if (typeof value === "string") {
116
+ return value;
117
+ }
118
+ return undefined;
119
+ }
@@ -1,3 +1,4 @@
1
+ import type { SimAws } from "../../aws/sim-aws.js";
1
2
  import type { SimAwsCaller } from "../../aws/caller/sim-aws-caller.js";
2
3
  import type { SimCdkOutContext } from "../cdk/sim-cdk-out-context.js";
3
4
  /**
@@ -18,13 +19,17 @@ export interface SimCfnStackUpdateContext {
18
19
  * values the deployment started with.
19
20
  */
20
21
  export declare class SimCfnStackDeployContext {
22
+ /** The simulation the Stack deploys into, which an update never moves. */
23
+ readonly simAws: SimAws;
21
24
  /** The CDK cloud assembly the Stack's template was synthesized into. */
22
25
  cdkOutContext: SimCdkOutContext | undefined;
23
26
  /** The principal the Stack's Resource work is authorized as. */
24
27
  caller: SimAwsCaller | undefined;
25
28
  /** The principal the Stack's CDK file assets are published as. */
26
29
  assetsCaller: SimAwsCaller | undefined;
27
- constructor(properties: SimCfnStackUpdateContext);
30
+ constructor(properties: SimCfnStackUpdateContext & {
31
+ readonly simAws: SimAws;
32
+ });
28
33
  /**
29
34
  * Take on what an update brings with it, for this and every later operation.
30
35
  *
@@ -7,6 +7,8 @@
7
7
  * values the deployment started with.
8
8
  */
9
9
  export class SimCfnStackDeployContext {
10
+ /** The simulation the Stack deploys into, which an update never moves. */
11
+ simAws;
10
12
  /** The CDK cloud assembly the Stack's template was synthesized into. */
11
13
  cdkOutContext;
12
14
  /** The principal the Stack's Resource work is authorized as. */
@@ -14,6 +16,7 @@ export class SimCfnStackDeployContext {
14
16
  /** The principal the Stack's CDK file assets are published as. */
15
17
  assetsCaller;
16
18
  constructor(properties) {
19
+ this.simAws = properties.simAws;
17
20
  this.cdkOutContext = properties.cdkOutContext;
18
21
  this.caller = properties.caller;
19
22
  this.assetsCaller = properties.assetsCaller;
@@ -4,7 +4,7 @@ import type { SimAwsCaller } from "../../aws/caller/sim-aws-caller.js";
4
4
  import type { SimAwsAccountRegionScope } from "../../aws/sim-aws-account-region-scope.js";
5
5
  import type { SimCfnBinding } from "../bind/sim-cfn-binding.js";
6
6
  import type { SimCdkOutContext } from "../cdk/sim-cdk-out-context.js";
7
- import { type SimCfnStackUpdateContext } from "./sim-cfn-stack-deploy-context.js";
7
+ import { SimCfnStackDeployContext, type SimCfnStackUpdateContext } from "./sim-cfn-stack-deploy-context.js";
8
8
  import type { SimCfnResource } from "../resource/sim-cfn-resource.js";
9
9
  import { SimCfnResourceRetention } from "../resource/delete/sim-cfn-resource-retention.js";
10
10
  import type { SimCfnTemplate } from "../template/sim-cfn-template.js";
@@ -53,12 +53,13 @@ interface SimCfnStackResourceOperationsProperties {
53
53
  * ordering of the work itself.
54
54
  */
55
55
  export declare class SimCfnStackResourceOperations {
56
+ /** What the Stack deploys from, into and as. */
57
+ readonly context: SimCfnStackDeployContext;
56
58
  private readonly simAws;
57
59
  private readonly accountRegionScope;
58
60
  private readonly stackName;
59
61
  private readonly bindings;
60
62
  private readonly resourceOrder;
61
- private readonly context;
62
63
  /**
63
64
  * Resources an update kept in simulated AWS.
64
65
  *
@@ -20,12 +20,13 @@ import { SimCfnStackResourceUpdates } from "./update/sim-cfn-stack-resource-upda
20
20
  * ordering of the work itself.
21
21
  */
22
22
  export class SimCfnStackResourceOperations {
23
+ /** What the Stack deploys from, into and as. */
24
+ context;
23
25
  simAws;
24
26
  accountRegionScope;
25
27
  stackName;
26
28
  bindings;
27
29
  resourceOrder;
28
- context;
29
30
  /**
30
31
  * Resources an update kept in simulated AWS.
31
32
  *
@@ -3,6 +3,7 @@ import { makeSimCfnStackResourceMap } from "./resource-map/sim-cfn-stack-resourc
3
3
  import { SimCfnStackResourceLookup } from "./resource-map/sim-cfn-stack-resource-lookup.js";
4
4
  import { SimCfnStackDeploymentLifecycle } from "./deploy/sim-cfn-stack-deployment-lifecycle.js";
5
5
  import { SimCfnStackResourceOperations } from "./sim-cfn-stack-resource-operations.js";
6
+ import { SimCfnReadHandlerAuthorizer } from "../registry/sim-cfn-read-handler-authorizer.js";
6
7
  import { SimCfnStackUpdateLifecycle } from "./update/sim-cfn-stack-update-lifecycle.js";
7
8
  import { SimCfnStackOutputs } from "./output/sim-cfn-stack-outputs.js";
8
9
  import { SimCfnStackOutputLookup } from "./output/sim-cfn-stack-output-lookup.js";
@@ -148,6 +149,14 @@ export class SimCfnStack {
148
149
  await this.updating.update({
149
150
  apply: async () => {
150
151
  await updater.apply();
152
+ // Resolving an output reads an untouched Resource through its read
153
+ // handler. A rollback makes no such call, so it has no step here.
154
+ await new SimCfnReadHandlerAuthorizer({
155
+ context: this.operations.context,
156
+ }).authorizeUpdate(updater.plan, {
157
+ updated: template,
158
+ resources: this.resourceMap,
159
+ });
151
160
  this.resolveOutputs();
152
161
  },
153
162
  rollBack: async () => {
@@ -1,5 +1,6 @@
1
1
  import type { SimCfnResource } from "../../resource/sim-cfn-resource.js";
2
2
  import { SimCfnResourceRetention } from "../../resource/delete/sim-cfn-resource-retention.js";
3
+ import type { CfnTemplateBodyRecord } from "../../template/sim-cfn-template.js";
3
4
  import { type SimCfnStackInPlaceUpdates } from "./sim-cfn-stack-resource-changes.js";
4
5
  import { type SimCfnStackResourceChange } from "./sim-cfn-stack-resource-change-pairs.js";
5
6
  interface SimCfnStackUpdatePlanProperties {
@@ -39,6 +40,11 @@ export declare class SimCfnStackUpdatePlan {
39
40
  */
40
41
  readonly creations: readonly SimCfnResource[];
41
42
  readonly updated: ReadonlyMap<string, SimCfnResource>;
43
+ /**
44
+ * The deployed Resources the new template describes unchanged, which the
45
+ * update leaves where they are.
46
+ */
47
+ readonly untouched: readonly SimCfnResource[];
42
48
  constructor(properties: SimCfnStackUpdatePlanProperties);
43
49
  /**
44
50
  * What the update's deletions are to leave in simulated AWS.
@@ -49,6 +55,11 @@ export declare class SimCfnStackUpdatePlan {
49
55
  * deletes that Resource.
50
56
  */
51
57
  retention(): SimCfnResourceRetention;
58
+ /**
59
+ * The untouched Resources whose attributes the template reads, through
60
+ * `Fn::GetAtt` or `Fn::Sub`.
61
+ */
62
+ untouchedReadBy(template: CfnTemplateBodyRecord): SimCfnResource[];
52
63
  /**
53
64
  * Whether the update changes any Resource at all.
54
65
  *
@@ -1,4 +1,5 @@
1
1
  import { SimCfnResourceRetention } from "../../resource/delete/sim-cfn-resource-retention.js";
2
+ import { simCfnAttributeReads } from "../../registry/sim-cfn-attribute-reads.js";
2
3
  import { simCfnStackResourceChanges, } from "./sim-cfn-stack-resource-changes.js";
3
4
  import { simCfnStackResourceChangePairs, } from "./sim-cfn-stack-resource-change-pairs.js";
4
5
  /**
@@ -33,6 +34,11 @@ export class SimCfnStackUpdatePlan {
33
34
  */
34
35
  creations;
35
36
  updated;
37
+ /**
38
+ * The deployed Resources the new template describes unchanged, which the
39
+ * update leaves where they are.
40
+ */
41
+ untouched;
36
42
  constructor(properties) {
37
43
  const { current, updated, inPlaceUpdates } = properties;
38
44
  const { replaced, updatedInPlace } = simCfnStackResourceChanges({
@@ -57,6 +63,14 @@ export class SimCfnStackUpdatePlan {
57
63
  return (!current.has(resource.logicalId) || replaced.has(resource.logicalId));
58
64
  })
59
65
  .toArray();
66
+ this.untouched = current
67
+ .values()
68
+ .filter(({ logicalId }) => {
69
+ return (updated.has(logicalId) &&
70
+ !replaced.has(logicalId) &&
71
+ !updatedInPlace.has(logicalId));
72
+ })
73
+ .toArray();
60
74
  }
61
75
  /**
62
76
  * What the update's deletions are to leave in simulated AWS.
@@ -74,6 +88,14 @@ export class SimCfnStackUpdatePlan {
74
88
  ])),
75
89
  });
76
90
  }
91
+ /**
92
+ * The untouched Resources whose attributes the template reads, through
93
+ * `Fn::GetAtt` or `Fn::Sub`.
94
+ */
95
+ untouchedReadBy(template) {
96
+ const reads = simCfnAttributeReads(template);
97
+ return this.untouched.filter(({ logicalId }) => reads.has(logicalId));
98
+ }
77
99
  /**
78
100
  * Whether the update changes any Resource at all.
79
101
  *
@@ -3,6 +3,7 @@ import type { SimAwsAccountRegionScope } from "../../../aws/sim-aws-account-regi
3
3
  import type { SimCfnResource } from "../../resource/sim-cfn-resource.js";
4
4
  import type { SimCfnTemplate } from "../../template/sim-cfn-template.js";
5
5
  import type { SimCfnStackResourceOperations } from "../sim-cfn-stack-resource-operations.js";
6
+ import { SimCfnStackUpdatePlan } from "./sim-cfn-stack-update-plan.js";
6
7
  /**
7
8
  * What CloudFormation answers an update that would change nothing.
8
9
  *
@@ -34,8 +35,9 @@ interface SimCfnStackUpdaterProperties {
34
35
  * SimCfnStackUpdateLifecycle owns the first and SimCfnStack the second.
35
36
  */
36
37
  export declare class SimCfnStackUpdater {
38
+ /** What the update does to the Stack's Resources. */
39
+ readonly plan: SimCfnStackUpdatePlan;
37
40
  private readonly properties;
38
- private readonly plan;
39
41
  constructor(properties: SimCfnStackUpdaterProperties);
40
42
  /**
41
43
  * Refuse an update that would do nothing, the way CloudFormation refuses one.
@@ -25,8 +25,9 @@ export const simCfnNoUpdatesMessage = "No updates are to be performed.";
25
25
  * SimCfnStackUpdateLifecycle owns the first and SimCfnStack the second.
26
26
  */
27
27
  export class SimCfnStackUpdater {
28
- properties;
28
+ /** What the update does to the Stack's Resources. */
29
29
  plan;
30
+ properties;
30
31
  constructor(properties) {
31
32
  const { accountRegionScope, background, resources, updated } = properties;
32
33
  this.properties = properties;
@@ -69,7 +69,7 @@ export class SimCognitoServiceController {
69
69
  // The web ACL sits in front of the endpoint rather than behind it, so a
70
70
  // request it blocks is answered before the method is judged. A write the
71
71
  // rules turned away gets WAF's 403 and never learns the endpoint reads.
72
- const blocked = await this.blocked(pool, segment, request);
72
+ const blocked = await this.blocked(pool, segment, serviceRequest);
73
73
  if (blocked !== undefined) {
74
74
  return blocked;
75
75
  }
@@ -90,14 +90,15 @@ export class SimCognitoServiceController {
90
90
  * A blocked request is answered before the document is read, so a verifier
91
91
  * the rules turn away gets 403 and no keys.
92
92
  */
93
- async blocked(pool, segment, request) {
93
+ async blocked(pool, segment, serviceRequest) {
94
94
  if (!simCognitoProtectedSegment(segment)) {
95
95
  return undefined;
96
96
  }
97
97
  const inspected = await this.webAcl.inspect({
98
98
  pool,
99
99
  cognito: simCognitoPoolScope(this.simAws, pool),
100
- request,
100
+ request: serviceRequest.request,
101
+ sourceIp: serviceRequest.sourceIp,
101
102
  });
102
103
  return inspected.blocked;
103
104
  }
@@ -44,6 +44,7 @@ export class SimCognitoDomainController {
44
44
  pool,
45
45
  cognito,
46
46
  request: serviceRequest.request,
47
+ sourceIp: serviceRequest.sourceIp,
47
48
  });
48
49
  if (inspected.blocked !== undefined) {
49
50
  return inspected.blocked;
@@ -95,6 +96,7 @@ function forwarded(serviceRequest, request) {
95
96
  request,
96
97
  caller: serviceRequest.caller,
97
98
  source: serviceRequest.source,
99
+ sourceIp: serviceRequest.sourceIp,
98
100
  body: serviceRequest.body,
99
101
  });
100
102
  }
@@ -6,6 +6,8 @@ interface SimCognitoInspectionInput {
6
6
  /** The simulated Cognito scope the pool belongs to. */
7
7
  readonly cognito: SimCognitoIdentityProvider;
8
8
  readonly request: Request;
9
+ /** The client address the request came from. */
10
+ readonly sourceIp: string;
9
11
  }
10
12
  /**
11
13
  * Puts a request to the web ACL in front of the pool it reached.
@@ -23,6 +23,7 @@ export class SimCognitoWebAclInspection {
23
23
  protection: input.cognito.webAcls(),
24
24
  resourceArn: input.pool.arn.value,
25
25
  request: input.request,
26
+ sourceIp: input.sourceIp,
26
27
  forwardBody: false,
27
28
  });
28
29
  }
@@ -9,4 +9,5 @@ export type { SimIamSigV4ExpectedScope } from "./sigv4/sim-iam-sigv4-expected-sc
9
9
  export { simAwsCallerHeaderName, simAwsCallerHeaderPrincipal, simAwsCallerHeaderValue, } from "./request/sim-aws-caller-header.js";
10
10
  export { type SimAwsRequestAuthMethod, SimAwsRequestCaller, } from "./request/sim-aws-request-caller.js";
11
11
  export { SimAwsRequestSource, simAwsSourceAccountHeaderName, simAwsSourceArnHeaderName, } from "./request/sim-aws-request-source.js";
12
+ export { simAwsRequestSourceIp, simAwsSourceIpHeaderName, } from "./request/sim-aws-source-ip-header.js";
12
13
  export { isSimAwsRequestAuthFailure, SimAwsInvalidCallerHeader, type SimAwsRequestAuthFailure, } from "./request/error/sim-aws-request-auth.error.js";
@@ -4,4 +4,5 @@ export { SimIamCredentialScopeMismatch, SimIamExpiredToken, SimIamIncompleteSign
4
4
  export { simAwsCallerHeaderName, simAwsCallerHeaderPrincipal, simAwsCallerHeaderValue, } from "./request/sim-aws-caller-header.js";
5
5
  export { SimAwsRequestCaller, } from "./request/sim-aws-request-caller.js";
6
6
  export { SimAwsRequestSource, simAwsSourceAccountHeaderName, simAwsSourceArnHeaderName, } from "./request/sim-aws-request-source.js";
7
+ export { simAwsRequestSourceIp, simAwsSourceIpHeaderName, } from "./request/sim-aws-source-ip-header.js";
7
8
  export { isSimAwsRequestAuthFailure, SimAwsInvalidCallerHeader, } from "./request/error/sim-aws-request-auth.error.js";
@@ -1,7 +1,7 @@
1
1
  import { SimIamSigV4Error } from "../../sigv4/error/sim-iam-sigv4.error.js";
2
2
  /**
3
3
  * Raised when the `x-sim-aws-caller` header does not name a principal the
4
- * simulator understands.
4
+ * simulator understands, or `x-sim-aws-source-ip` names no address.
5
5
  *
6
6
  * This is a simulator control header rather than anything real AWS defines, so
7
7
  * a bad value is the caller's mistake in using Yulin, not a failed AWS
@@ -1,7 +1,7 @@
1
1
  import { SimIamSigV4Error } from "../../sigv4/error/sim-iam-sigv4.error.js";
2
2
  /**
3
3
  * Raised when the `x-sim-aws-caller` header does not name a principal the
4
- * simulator understands.
4
+ * simulator understands, or `x-sim-aws-source-ip` names no address.
5
5
  *
6
6
  * This is a simulator control header rather than anything real AWS defines, so
7
7
  * a bad value is the caller's mistake in using Yulin, not a failed AWS
@@ -2,7 +2,8 @@
2
2
  * Header names that are instructions to the simulator rather than part of the
3
3
  * request being simulated.
4
4
  *
5
- * They state who a request is from and what it is for, so anything passing a
5
+ * They state who a request is from, where it came from and what it is for, so
6
+ * anything passing a
6
7
  * request on to a simulated service has to decide what to do with them rather
7
8
  * than forward them by accident: the HTTP boundary strips them once the
8
9
  * request has been attributed, and sim CloudFront strips a viewer's before
@@ -1,10 +1,12 @@
1
1
  import { simAwsCallerHeaderName } from "./sim-aws-caller-header.js";
2
+ import { simAwsSourceIpHeaderName } from "./sim-aws-source-ip-header.js";
2
3
  import { simAwsSourceAccountHeaderName, simAwsSourceArnHeaderName, } from "./sim-aws-request-source.js";
3
4
  /**
4
5
  * Header names that are instructions to the simulator rather than part of the
5
6
  * request being simulated.
6
7
  *
7
- * They state who a request is from and what it is for, so anything passing a
8
+ * They state who a request is from, where it came from and what it is for, so
9
+ * anything passing a
8
10
  * request on to a simulated service has to decide what to do with them rather
9
11
  * than forward them by accident: the HTTP boundary strips them once the
10
12
  * request has been attributed, and sim CloudFront strips a viewer's before
@@ -14,6 +16,7 @@ export const simAwsControlHeaderNames = [
14
16
  simAwsCallerHeaderName,
15
17
  simAwsSourceArnHeaderName,
16
18
  simAwsSourceAccountHeaderName,
19
+ simAwsSourceIpHeaderName,
17
20
  ];
18
21
  /**
19
22
  * Remove the simulator's control headers from a set of request headers.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The header naming the client address a request into simulated AWS comes
3
+ * from.
4
+ *
5
+ * A request arrives in process or over loopback, so there is no remote address
6
+ * for the simulation to read. Whatever decides by where a request came from,
7
+ * such as a web ACL's IP reputation and anonymous IP rules, reads this instead,
8
+ * and a test sends it to say which client a request stands for.
9
+ */
10
+ export declare const simAwsSourceIpHeaderName = "x-sim-aws-source-ip";
11
+ /**
12
+ * Read the client address a request states, or the loopback address when it
13
+ * states none.
14
+ *
15
+ * The header holds one IPv4 or IPv6 address. A value that is neither is
16
+ * refused rather than read as loopback, since a test that misspelt an address
17
+ * would otherwise pass for the wrong reason.
18
+ */
19
+ export declare function simAwsRequestSourceIp(headers: Headers): string;
@@ -0,0 +1,32 @@
1
+ import { isIP } from "node:net";
2
+ import { simAwsProxiedSourceIp } from "../../../serve/http/sim-aws-proxied-connection.js";
3
+ import { SimAwsInvalidCallerHeader } from "./error/sim-aws-request-auth.error.js";
4
+ /**
5
+ * The header naming the client address a request into simulated AWS comes
6
+ * from.
7
+ *
8
+ * A request arrives in process or over loopback, so there is no remote address
9
+ * for the simulation to read. Whatever decides by where a request came from,
10
+ * such as a web ACL's IP reputation and anonymous IP rules, reads this instead,
11
+ * and a test sends it to say which client a request stands for.
12
+ */
13
+ export const simAwsSourceIpHeaderName = "x-sim-aws-source-ip";
14
+ /**
15
+ * Read the client address a request states, or the loopback address when it
16
+ * states none.
17
+ *
18
+ * The header holds one IPv4 or IPv6 address. A value that is neither is
19
+ * refused rather than read as loopback, since a test that misspelt an address
20
+ * would otherwise pass for the wrong reason.
21
+ */
22
+ export function simAwsRequestSourceIp(headers) {
23
+ const value = headers.get(simAwsSourceIpHeaderName)?.trim();
24
+ if (value === undefined || value === "") {
25
+ return simAwsProxiedSourceIp;
26
+ }
27
+ if (isIP(value) === 0) {
28
+ throw new SimAwsInvalidCallerHeader(`${simAwsSourceIpHeaderName} value ${value} must be one IPv4 or IPv6 ` +
29
+ `address`);
30
+ }
31
+ return value;
32
+ }
@@ -56,6 +56,7 @@ export class SimStatesExecutionStart {
56
56
  background: this.#background,
57
57
  tasks: this.#tasks,
58
58
  roleArn: stateMachine.roleArn,
59
+ stateMachineArn: stateMachine.arn,
59
60
  })({
60
61
  definition: stateMachine.parsedDefinition,
61
62
  record: execution,
@@ -14,6 +14,7 @@ export async function runSimStatesTask(state, input, context) {
14
14
  target: state.target,
15
15
  payload: simStatesEffectiveInput(input, state, context.contextObject),
16
16
  roleArn: context.roleArn,
17
+ stateMachineArn: context.stateMachineArn,
17
18
  });
18
19
  const output = simStatesEffectiveOutput(input, result, state, context.contextObject);
19
20
  return state.Next === undefined
@@ -71,6 +71,7 @@ export interface SimStatesWalkContext {
71
71
  * The state machine's execution role, which a task assumes.
72
72
  */
73
73
  readonly roleArn: string;
74
+ readonly stateMachineArn: string;
74
75
  /**
75
76
  * What the walk is recording itself on, which a `Parallel` state's branch
76
77
  * hangs off.
@@ -11,6 +11,7 @@ interface SimStatesWalksProperties {
11
11
  * The state machine's execution role, which a task assumes.
12
12
  */
13
13
  readonly roleArn: string;
14
+ readonly stateMachineArn: string;
14
15
  }
15
16
  /**
16
17
  * How one execution walks a set of states, its `Parallel` branches included.
@@ -16,6 +16,7 @@ export function simStatesWalks(properties) {
16
16
  contextObject: child.contextObject,
17
17
  tasks: properties.tasks,
18
18
  roleArn: properties.roleArn,
19
+ stateMachineArn: properties.stateMachineArn,
19
20
  walkChild: walks,
20
21
  },
21
22
  ...(child.onSettled !== undefined && { onSettled: child.onSettled }),
@@ -30,7 +30,12 @@ export class SimAwsStatesTaskTargets {
30
30
  const { stateName, target } = invocation;
31
31
  const role = simStatesExecutionRoleTarget(invocation.roleArn, stateName);
32
32
  const roleScope = this.#simAws.accountRegionScope(role.accountId, this.#accountRegionScope.regionName);
33
- const caller = await assumeSimStatesExecutionRole(role, roleScope);
33
+ // Step Functions supplies the state machine as the trust policy source.
34
+ // https://docs.aws.amazon.com/step-functions/latest/dg/procedure-create-iam-role.html
35
+ const caller = await assumeSimStatesExecutionRole(role, roleScope, {
36
+ arn: invocation.stateMachineArn,
37
+ accountId: this.#accountRegionScope.accountId,
38
+ });
34
39
  return await target.run({
35
40
  stateName,
36
41
  payload: invocation.payload,
@@ -1,6 +1,7 @@
1
1
  import type { SimAwsCaller } from "../../aws/caller/sim-aws-caller.js";
2
2
  import type { SimAwsAccountRegionContainer } from "../../aws/sim-aws-account-region-scope.js";
3
3
  import { type SimServiceRoleTarget } from "../../sts/service-role/sim-service-role-target.js";
4
+ import type { SimServiceRoleSource } from "../../sts/service-role/sim-service-role-source.js";
4
5
  /**
5
6
  * The service principal a state machine's execution role trusts.
6
7
  */
@@ -21,4 +22,4 @@ export declare function simStatesExecutionRoleTarget(roleArn: string, stateName:
21
22
  * rule, which reaches a function as a service principal and is admitted by the
22
23
  * function's resource policy.
23
24
  */
24
- export declare function assumeSimStatesExecutionRole(target: SimServiceRoleTarget, scope: SimAwsAccountRegionContainer): Promise<SimAwsCaller>;
25
+ export declare function assumeSimStatesExecutionRole(target: SimServiceRoleTarget, scope: SimAwsAccountRegionContainer, source: SimServiceRoleSource): Promise<SimAwsCaller>;