@gugananuvem/aws-local-simulator 1.0.35 → 1.0.39

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 (149) hide show
  1. package/README.md +662 -658
  2. package/package.json +10 -3
  3. package/src/config/default-config.js +71 -0
  4. package/src/config/env-loader.js +4 -2
  5. package/src/middleware/authorization.js +271 -0
  6. package/src/middleware/cloudtrail-logger.js +333 -0
  7. package/src/middleware/error-handler.js +138 -0
  8. package/src/middleware/index.js +79 -0
  9. package/src/middleware/policy-enforcement.js +407 -0
  10. package/src/server.js +74 -4
  11. package/src/services/acm/index.js +66 -0
  12. package/src/services/acm/models/certificate.js +202 -0
  13. package/src/services/acm/server.js +224 -0
  14. package/src/services/acm/simulator.js +293 -0
  15. package/src/services/alb/index.js +104 -0
  16. package/src/services/alb/models/loadBalancer.js +88 -0
  17. package/src/services/alb/models/targetGroup.js +128 -0
  18. package/src/services/alb/server.js +160 -0
  19. package/src/services/alb/simulator.js +262 -0
  20. package/src/services/apigateway/index.js +22 -0
  21. package/src/services/apigateway/server.js +247 -35
  22. package/src/services/apigateway/simulator.js +780 -26
  23. package/src/services/asg/index.js +100 -0
  24. package/src/services/asg/models/autoScalingGroup.js +110 -0
  25. package/src/services/asg/models/launchTemplate.js +41 -0
  26. package/src/services/asg/models/scalingPolicy.js +51 -0
  27. package/src/services/asg/server.js +236 -0
  28. package/src/services/asg/simulator.js +410 -0
  29. package/src/services/aurora/cluster-manager.js +731 -0
  30. package/src/services/aurora/data-api.js +514 -0
  31. package/src/services/aurora/db-engine.js +270 -0
  32. package/src/services/aurora/index.js +159 -0
  33. package/src/services/aurora/rds-api.js +189 -0
  34. package/src/services/aurora/server.js +213 -0
  35. package/src/services/aurora/sql-translator.js +334 -0
  36. package/src/services/cloudformation/index.js +2 -2
  37. package/src/services/cloudformation/server.js +1 -0
  38. package/src/services/cloudfront/cache-engine.js +225 -0
  39. package/src/services/cloudfront/geo-restrictions.js +377 -0
  40. package/src/services/cloudfront/index.js +220 -0
  41. package/src/services/cloudfront/models/behavior.js +158 -0
  42. package/src/services/cloudfront/models/distribution.js +284 -0
  43. package/src/services/cloudfront/models/index.js +99 -0
  44. package/src/services/cloudfront/models/invalidation.js +109 -0
  45. package/src/services/cloudfront/models/origin.js +155 -0
  46. package/src/services/cloudfront/origin-router.js +552 -0
  47. package/src/services/cloudfront/origin-validator.js +398 -0
  48. package/src/services/cloudfront/server.js +512 -0
  49. package/src/services/cloudfront/signed-url-generator.js +377 -0
  50. package/src/services/cloudfront/simulator.js +425 -0
  51. package/src/services/cloudfront/store.js +326 -0
  52. package/src/services/cloudshell/env-builder.js +27 -0
  53. package/src/services/cloudshell/index.js +48 -0
  54. package/src/services/cloudshell/routes.js +60 -0
  55. package/src/services/cloudshell/session-manager.js +226 -0
  56. package/src/services/cloudshell/static/.gitkeep +0 -0
  57. package/src/services/cloudshell/static/index.html +406 -0
  58. package/src/services/cloudshell/websocket-handler.js +107 -0
  59. package/src/services/cloudtrail/index.js +2 -3
  60. package/src/services/cloudtrail/server.js +68 -0
  61. package/src/services/cognito/server.js +4 -1
  62. package/src/services/dynamodb/server.js +4 -1
  63. package/src/services/dynamodb/simulator.js +2 -1
  64. package/src/services/ec2/index.js +101 -0
  65. package/src/services/ec2/instanceServer.js +311 -0
  66. package/src/services/ec2/models/ami.js +39 -0
  67. package/src/services/ec2/models/instance.js +98 -0
  68. package/src/services/ec2/models/networkInterface.js +74 -0
  69. package/src/services/ec2/models/securityGroup.js +71 -0
  70. package/src/services/ec2/server.js +350 -0
  71. package/src/services/ec2/simulator.js +436 -0
  72. package/src/services/eventbridge/server.js +36 -0
  73. package/src/services/eventbridge/simulator.js +230 -45
  74. package/src/services/iam/index.js +65 -0
  75. package/src/services/iam/middleware.js +99 -0
  76. package/src/services/iam/server.js +331 -0
  77. package/src/services/iam/simulator.js +1432 -0
  78. package/src/services/index.js +28 -0
  79. package/src/services/kinesis-analytics/index.js +105 -0
  80. package/src/services/kinesis-analytics/models/application.js +325 -0
  81. package/src/services/kinesis-analytics/models/index.js +12 -0
  82. package/src/services/kinesis-analytics/server.js +250 -0
  83. package/src/services/kinesis-analytics/simulator.js +407 -0
  84. package/src/services/kinesis-analytics/store.js +176 -0
  85. package/src/services/kinesis-data-streams/index.js +106 -0
  86. package/src/services/kinesis-data-streams/models/index.js +12 -0
  87. package/src/services/kinesis-data-streams/models/record.js +70 -0
  88. package/src/services/kinesis-data-streams/models/stream.js +280 -0
  89. package/src/services/kinesis-data-streams/server.js +255 -0
  90. package/src/services/kinesis-data-streams/simulator.js +514 -0
  91. package/src/services/kinesis-data-streams/store.js +163 -0
  92. package/src/services/kinesis-firehose/index.js +106 -0
  93. package/src/services/kinesis-firehose/models/delivery-stream.js +265 -0
  94. package/src/services/kinesis-firehose/models/index.js +10 -0
  95. package/src/services/kinesis-firehose/server.js +215 -0
  96. package/src/services/kinesis-firehose/simulator.js +388 -0
  97. package/src/services/kinesis-firehose/store.js +163 -0
  98. package/src/services/kms/server.js +4 -1
  99. package/src/services/lambda/index.js +26 -0
  100. package/src/services/lambda/server.js +12 -1
  101. package/src/services/lambda/simulator.js +4 -0
  102. package/src/services/opensearch/index.js +105 -0
  103. package/src/services/opensearch/models/document.js +115 -0
  104. package/src/services/opensearch/models/index.js +73 -0
  105. package/src/services/opensearch/server.js +310 -0
  106. package/src/services/opensearch/simulator.js +605 -0
  107. package/src/services/opensearch/store.js +162 -0
  108. package/src/services/organizations/control-tower-simulator.js +321 -0
  109. package/src/services/organizations/control-tower-store.js +182 -0
  110. package/src/services/organizations/iam-integration.js +413 -0
  111. package/src/services/organizations/index.js +172 -0
  112. package/src/services/organizations/models/index.js +13 -0
  113. package/src/services/organizations/models/invitation.js +48 -0
  114. package/src/services/organizations/models/organization.js +566 -0
  115. package/src/services/organizations/models/role.js +244 -0
  116. package/src/services/organizations/models/scp.js +131 -0
  117. package/src/services/organizations/server.js +736 -0
  118. package/src/services/organizations/simulator.js +593 -0
  119. package/src/services/organizations/store.js +235 -0
  120. package/src/services/organizations/vpc-integration.js +453 -0
  121. package/src/services/route53/index.js +67 -0
  122. package/src/services/route53/models/healthCheck.js +101 -0
  123. package/src/services/route53/models/hostedZone.js +37 -0
  124. package/src/services/route53/models/resourceRecord.js +106 -0
  125. package/src/services/route53/server.js +841 -0
  126. package/src/services/route53/simulator.js +350 -0
  127. package/src/services/s3/index.js +62 -0
  128. package/src/services/s3/presigned-url-generator.js +337 -0
  129. package/src/services/s3/server.js +231 -0
  130. package/src/services/s3/simulator.js +551 -4
  131. package/src/services/sns/index.js +31 -0
  132. package/src/services/sns/server.js +9 -0
  133. package/src/services/sqs/index.js +38 -0
  134. package/src/services/sqs/server.js +57 -4
  135. package/src/services/sqs/simulator.js +423 -33
  136. package/src/services/sts/simulator.js +209 -17
  137. package/src/services/vpc/README.md +459 -0
  138. package/src/services/vpc/ec2ResponseFormatter.js +431 -0
  139. package/src/services/vpc/index.js +90 -0
  140. package/src/services/vpc/models/internetGateway.js +71 -0
  141. package/src/services/vpc/models/routeTable.js +160 -0
  142. package/src/services/vpc/models/subnet.js +48 -0
  143. package/src/services/vpc/models/vpc.js +37 -0
  144. package/src/services/vpc/models/vpcEndpoint.js +100 -0
  145. package/src/services/vpc/models/vpcGateway.js +134 -0
  146. package/src/services/vpc/server.js +836 -0
  147. package/src/services/vpc/simulator.js +613 -0
  148. package/src/utils/policy-cache.js +215 -0
  149. package/aws-config +0 -154
@@ -2,61 +2,253 @@ const crypto = require('crypto');
2
2
  const logger = require('../../utils/logger');
3
3
 
4
4
  class STSSimulator {
5
- constructor(config) {
5
+ constructor(config, organizationsService = null) {
6
6
  this.config = config;
7
+ this.organizationsService = organizationsService;
7
8
  this.assumedRoles = new Map();
9
+ this.sessions = new Map(); // Track active sessions
8
10
  }
9
11
 
10
12
  async initialize() {
11
13
  logger.debug('Inicializando STS Simulator...');
12
14
  }
13
15
 
16
+ /**
17
+ * AssumeRole - com integração a Organizations
18
+ * Retorna temporary credentials com SessionToken JWT
19
+ */
14
20
  assumeRole(params = {}) {
15
- const { RoleArn, RoleSessionName, DurationSeconds = 3600 } = params;
21
+ const { RoleArn, RoleSessionName, DurationSeconds = 3600, ExternalId = null, SerialNumber = null, TokenCode = null } = params;
22
+
16
23
  if (!RoleArn) throw new Error('RoleArn is required');
17
24
  if (!RoleSessionName) throw new Error('RoleSessionName is required');
18
25
 
19
- const accessKeyId = `ASIA${crypto.randomBytes(8).toString('hex').toUpperCase()}`;
20
- const secretKey = crypto.randomBytes(20).toString('hex');
21
- const sessionToken = crypto.randomBytes(64).toString('base64');
22
- const expiration = new Date(Date.now() + DurationSeconds * 1000).toISOString();
26
+ // Extrair accountId e roleName do ARN
27
+ // Format: arn:aws:iam::123456789012:role/role-name
28
+ const arnParts = RoleArn.match(/arn:aws:iam::(\d+):role\/(.+)/);
29
+ if (!arnParts) throw new Error('Invalid RoleArn format');
30
+
31
+ const [, accountId, roleName] = arnParts;
32
+
33
+ // Validar role existe na organização (se Organizations está disponível)
34
+ if (this.organizationsService?.organizationsSimulator?.roles) {
35
+ const roleExists = this.organizationsService.organizationsSimulator.roles.has(RoleArn);
36
+ if (!roleExists) {
37
+ throw new Error(`Role ${RoleArn} does not exist`);
38
+ }
39
+ }
40
+
41
+ // Gerar temporary credentials
42
+ const credentials = this.generateTemporaryCredentials(
43
+ accountId,
44
+ RoleArn,
45
+ RoleSessionName,
46
+ DurationSeconds
47
+ );
48
+
49
+ // Armazenar session para rastreamento
50
+ this.sessions.set(credentials.sessionId, {
51
+ roleArn: RoleArn,
52
+ sessionName: RoleSessionName,
53
+ createdAt: Date.now(),
54
+ expiresAt: credentials.expiresAtMs,
55
+ accountId,
56
+ accessKeyId: credentials.accessKeyId
57
+ });
58
+
59
+ const expiration = new Date(credentials.expiresAtMs).toISOString();
23
60
  const assumedRoleId = `AROA${crypto.randomBytes(8).toString('hex').toUpperCase()}:${RoleSessionName}`;
24
61
 
25
62
  return {
26
- Credentials: { AccessKeyId: accessKeyId, SecretAccessKey: secretKey, SessionToken: sessionToken, Expiration: expiration },
27
- AssumedRoleUser: { AssumedRoleId: assumedRoleId, Arn: `${RoleArn}/${RoleSessionName}` },
28
- PackedPolicySize: null
63
+ Credentials: {
64
+ AccessKeyId: credentials.accessKeyId,
65
+ SecretAccessKey: credentials.secretAccessKey,
66
+ SessionToken: credentials.sessionToken,
67
+ Expiration: expiration
68
+ },
69
+ AssumedRoleUser: {
70
+ AssumedRoleId: assumedRoleId,
71
+ Arn: `${RoleArn}/${RoleSessionName}`
72
+ },
73
+ PackedPolicySize: 6
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Gerar credentials temporárias com JWT SessionToken
79
+ * SessionToken contém informações do role para validação posterior
80
+ */
81
+ generateTemporaryCredentials(accountId, roleArn, sessionName, durationSeconds) {
82
+ const now = Date.now();
83
+ const expiresAtMs = now + (durationSeconds * 1000);
84
+
85
+ // AccessKeyId com prefixo ASIA (indica temporary credentials)
86
+ const accessKeyId = `ASIA${crypto.randomBytes(8).toString('hex').toUpperCase()}`;
87
+ const secretAccessKey = crypto.randomBytes(20).toString('hex');
88
+
89
+ // Gerar JWT SessionToken com informações do role
90
+ const sessionId = crypto.randomBytes(16).toString('hex');
91
+
92
+ const payload = {
93
+ sessionId,
94
+ accountId,
95
+ assumedRole: roleArn,
96
+ sessionName,
97
+ principal: 'unknown',
98
+ issuedAt: now,
99
+ expiresAt: expiresAtMs,
100
+ accessKeyId,
101
+ secretAccessKey,
102
+ iss: 'aws-local-simulator-sts',
103
+ type: 'temporary-credentials'
104
+ };
105
+
106
+ // Criar JWT simples
107
+ const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url');
108
+ const payloadEncoded = Buffer.from(JSON.stringify(payload)).toString('base64url');
109
+
110
+ const signature = crypto
111
+ .createHmac('sha256', this.config.jwtSecret || 'local-simulator-secret')
112
+ .update(`${header}.${payloadEncoded}`)
113
+ .digest('base64url');
114
+
115
+ const sessionToken = `${header}.${payloadEncoded}.${signature}`;
116
+
117
+ return {
118
+ sessionId,
119
+ accessKeyId,
120
+ secretAccessKey,
121
+ sessionToken,
122
+ expiresAtMs,
123
+ accountId,
124
+ roleArn
29
125
  };
30
126
  }
31
127
 
32
- getCallerIdentity(params = {}) {
128
+ /**
129
+ * Validar SessionToken JWT
130
+ */
131
+ validateSessionToken(token) {
132
+ try {
133
+ const parts = token.split('.');
134
+ if (parts.length !== 3) return null;
135
+
136
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));
137
+
138
+ if (payload.expiresAt < Date.now()) {
139
+ return null;
140
+ }
141
+
142
+ return payload;
143
+ } catch (error) {
144
+ logger.debug('SessionToken validation error:', error.message);
145
+ return null;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * GetCallerIdentity - Retorna informações do principal
151
+ */
152
+ getCallerIdentity(params = {}, sessionToken = null) {
153
+ if (sessionToken) {
154
+ const payload = this.validateSessionToken(sessionToken);
155
+ if (payload) {
156
+ return {
157
+ UserId: payload.sessionId,
158
+ Account: payload.accountId,
159
+ Arn: payload.assumedRole,
160
+ SessionToken: sessionToken,
161
+ Type: 'AssumedRole'
162
+ };
163
+ }
164
+ }
165
+
33
166
  return {
34
167
  UserId: 'AKIAIOSFODNN7EXAMPLE',
35
168
  Account: '123456789012',
36
- Arn: 'arn:aws:iam::123456789012:user/local-simulator'
169
+ Arn: 'arn:aws:iam::123456789012:user/local-simulator',
170
+ Type: 'IAMUser'
37
171
  };
38
172
  }
39
173
 
174
+ /**
175
+ * GetSessionToken - Gera session token para MFA
176
+ */
40
177
  getSessionToken(params = {}) {
41
178
  const { DurationSeconds = 3600 } = params;
179
+
180
+ const credentials = this.generateTemporaryCredentials(
181
+ '123456789012',
182
+ 'arn:aws:iam::123456789012:root',
183
+ 'mfa-session',
184
+ DurationSeconds
185
+ );
186
+
42
187
  return {
43
188
  Credentials: {
44
- AccessKeyId: `ASIA${crypto.randomBytes(8).toString('hex').toUpperCase()}`,
45
- SecretAccessKey: crypto.randomBytes(20).toString('hex'),
46
- SessionToken: crypto.randomBytes(64).toString('base64'),
47
- Expiration: new Date(Date.now() + DurationSeconds * 1000).toISOString()
189
+ AccessKeyId: credentials.accessKeyId,
190
+ SecretAccessKey: credentials.secretAccessKey,
191
+ SessionToken: credentials.sessionToken,
192
+ Expiration: new Date(credentials.expiresAtMs).toISOString()
48
193
  }
49
194
  };
50
195
  }
51
196
 
197
+ /**
198
+ * AssumeRoleWithWebIdentity
199
+ */
52
200
  assumeRoleWithWebIdentity(params = {}) {
53
- return this.assumeRole({ ...params, RoleSessionName: params.RoleSessionName || 'web-identity-session' });
201
+ return this.assumeRole({
202
+ ...params,
203
+ RoleSessionName: params.RoleSessionName || 'web-identity-session'
204
+ });
54
205
  }
55
206
 
207
+ /**
208
+ * AssumeRoleWithSAML
209
+ */
56
210
  assumeRoleWithSAML(params = {}) {
57
- return this.assumeRole({ ...params, RoleSessionName: params.RoleSessionName || 'saml-session' });
211
+ return this.assumeRole({
212
+ ...params,
213
+ RoleSessionName: params.RoleSessionName || 'saml-session'
214
+ });
215
+ }
216
+
217
+ /**
218
+ * GetStats
219
+ */
220
+ getStats() {
221
+ const now = Date.now();
222
+ let activeSessions = 0;
223
+ let expiredSessions = 0;
224
+
225
+ for (const session of this.sessions.values()) {
226
+ if (session.expiresAt > now) {
227
+ activeSessions++;
228
+ } else {
229
+ expiredSessions++;
230
+ }
231
+ }
232
+
233
+ return {
234
+ activeSessions,
235
+ expiredSessions,
236
+ totalSessions: this.sessions.size
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Reset
242
+ */
243
+ async reset() {
244
+ this.assumedRoles.clear();
245
+ this.sessions.clear();
246
+ logger.debug('STS Simulator reset');
58
247
  }
59
248
 
249
+ /**
250
+ * Generate error response
251
+ */
60
252
  generateErrorResponse(code, message) {
61
253
  return `<?xml version="1.0" encoding="UTF-8"?>
62
254
  <ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">