@gugananuvem/aws-local-simulator 1.0.11 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -69
- package/package.json +2 -2
- package/src/config/config-loader.js +2 -0
- package/src/config/default-config.js +2 -0
- package/src/server.js +3 -1
- package/src/services/apigateway/index.js +5 -3
- package/src/services/apigateway/server.js +53 -0
- package/src/services/cognito/server.js +54 -3
- package/src/services/cognito/simulator.js +269 -2
- package/src/services/lambda/handler-loader.js +13 -2
- package/src/services/lambda/index.js +2 -1
- package/src/services/lambda/server.js +32 -39
- package/src/services/lambda/simulator.js +44 -157
- package/src/services/sqs/server.js +88 -16
- package/src/services/sqs/simulator.js +79 -298
- package/src/services/sts/index.js +37 -0
- package/src/services/sts/server.js +142 -0
- package/src/services/sts/simulator.js +69 -0
package/README.md
CHANGED
|
@@ -13,10 +13,11 @@ Simulador local completo para serviços AWS. Desenvolva e teste suas aplicaçõe
|
|
|
13
13
|
| DynamoDB | ✅ | 8000 | Banco de dados NoSQL |
|
|
14
14
|
| S3 | ✅ | 4566 | Armazenamento de objetos |
|
|
15
15
|
| SQS | ✅ | 9324 | Filas de mensagens |
|
|
16
|
-
| Lambda | ✅ | 3001 | Funções serverless |
|
|
16
|
+
| Lambda | ✅ | 3001 | Funções serverless (invocação por nome) |
|
|
17
17
|
| Cognito | ✅ | 9229 | Autenticação e autorização |
|
|
18
18
|
| API Gateway | ✅ | 4567 | APIs REST e HTTP |
|
|
19
|
-
|
|
|
19
|
+
| STS | ✅ | 9326 | Credenciais temporárias (AssumeRole, GetCallerIdentity) |
|
|
20
|
+
| ECS/Fargate | 🚧 | 8080 | Orquestração de containers (em desenvolvimento) |
|
|
20
21
|
| SNS | 🚧 | 9911 | Notificações (em desenvolvimento) |
|
|
21
22
|
| EventBridge | 🚧 | 4010 | Barramento de eventos (em desenvolvimento) |
|
|
22
23
|
|
|
@@ -25,8 +26,11 @@ Simulador local completo para serviços AWS. Desenvolva e teste suas aplicaçõe
|
|
|
25
26
|
```bash
|
|
26
27
|
npm install --save-dev aws-local-simulator
|
|
27
28
|
```
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
|
|
30
|
+
## 🚀 Uso Rápido
|
|
31
|
+
|
|
32
|
+
### 1. Crie um arquivo de configuração `aws-local-simulator.json`:
|
|
33
|
+
|
|
30
34
|
```json
|
|
31
35
|
{
|
|
32
36
|
"services": {
|
|
@@ -35,11 +39,12 @@ npm install --save-dev aws-local-simulator
|
|
|
35
39
|
"sqs": true,
|
|
36
40
|
"lambda": true,
|
|
37
41
|
"cognito": true,
|
|
38
|
-
"apigateway": true
|
|
42
|
+
"apigateway": true,
|
|
43
|
+
"sts": true
|
|
39
44
|
},
|
|
40
45
|
"lambdas": [
|
|
41
46
|
{
|
|
42
|
-
"
|
|
47
|
+
"name": "my-function",
|
|
43
48
|
"handler": "./src/handlers/users.js",
|
|
44
49
|
"env": {
|
|
45
50
|
"TABLE_NAME": "users-table"
|
|
@@ -50,18 +55,17 @@ npm install --save-dev aws-local-simulator
|
|
|
50
55
|
"tables": [
|
|
51
56
|
{
|
|
52
57
|
"TableName": "users-table",
|
|
53
|
-
"KeySchema": [
|
|
54
|
-
|
|
55
|
-
],
|
|
56
|
-
"AttributeDefinitions": [
|
|
57
|
-
{ "AttributeName": "id", "AttributeType": "S" }
|
|
58
|
-
]
|
|
58
|
+
"KeySchema": [{ "AttributeName": "id", "KeyType": "HASH" }],
|
|
59
|
+
"AttributeDefinitions": [{ "AttributeName": "id", "AttributeType": "S" }]
|
|
59
60
|
}
|
|
60
61
|
]
|
|
61
62
|
},
|
|
62
63
|
"s3": {
|
|
63
64
|
"buckets": ["my-bucket"]
|
|
64
65
|
},
|
|
66
|
+
"sqs": {
|
|
67
|
+
"queues": ["my-queue", "dead-letter-queue"]
|
|
68
|
+
},
|
|
65
69
|
"cognito": {
|
|
66
70
|
"userPools": [
|
|
67
71
|
{
|
|
@@ -73,80 +77,86 @@ npm install --save-dev aws-local-simulator
|
|
|
73
77
|
}
|
|
74
78
|
```
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
### 2. Inicie o simulador:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Via CLI
|
|
78
84
|
npx aws-local-simulator start
|
|
79
85
|
|
|
80
86
|
# Ou via código
|
|
81
87
|
const { AWSLocalSimulator } = require('aws-local-simulator');
|
|
82
88
|
const simulator = new AWSLocalSimulator();
|
|
83
89
|
await simulator.start();
|
|
90
|
+
```
|
|
84
91
|
|
|
85
|
-
|
|
92
|
+
### 3. Configure seu código para usar os serviços locais:
|
|
86
93
|
|
|
87
94
|
```javascript
|
|
88
|
-
|
|
89
|
-
const { dynamoDB, s3, sqs, cognito, apigateway } = require('aws-local-simulator/aws-config');
|
|
95
|
+
const { dynamoDB, s3, sqs, cognito } = require('aws-local-simulator/aws-config');
|
|
90
96
|
|
|
91
|
-
// Use como normalmente faria
|
|
92
97
|
await dynamoDB.send(new PutCommand({
|
|
93
98
|
TableName: 'users-table',
|
|
94
99
|
Item: { id: '123', name: 'John' }
|
|
95
100
|
}));
|
|
96
101
|
```
|
|
97
102
|
|
|
98
|
-
🔧 Configuração por Variáveis de Ambiente
|
|
103
|
+
## 🔧 Configuração por Variáveis de Ambiente
|
|
99
104
|
|
|
100
105
|
| Variável | Descrição | Padrão |
|
|
101
106
|
|---------|----------|-------|
|
|
102
|
-
| AWS_LOCAL_SIMULATOR_DYNAMODB |Habilita DynamoDB | true |
|
|
103
|
-
| AWS_LOCAL_SIMULATOR_S3 |Habilita S3 | true |
|
|
104
|
-
| AWS_LOCAL_SIMULATOR_SQS |Habilita SQS | true |
|
|
105
|
-
| AWS_LOCAL_SIMULATOR_LAMBDA |Habilita Lambda | true |
|
|
106
|
-
| AWS_LOCAL_SIMULATOR_COGNITO |Habilita Cognito | false |
|
|
107
|
-
| AWS_LOCAL_SIMULATOR_APIGATEWAY |Habilita API Gateway | false |
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
107
|
+
| AWS_LOCAL_SIMULATOR_DYNAMODB | Habilita DynamoDB | true |
|
|
108
|
+
| AWS_LOCAL_SIMULATOR_S3 | Habilita S3 | true |
|
|
109
|
+
| AWS_LOCAL_SIMULATOR_SQS | Habilita SQS | true |
|
|
110
|
+
| AWS_LOCAL_SIMULATOR_LAMBDA | Habilita Lambda | true |
|
|
111
|
+
| AWS_LOCAL_SIMULATOR_COGNITO | Habilita Cognito | false |
|
|
112
|
+
| AWS_LOCAL_SIMULATOR_APIGATEWAY | Habilita API Gateway | false |
|
|
113
|
+
| AWS_LOCAL_SIMULATOR_STS | Habilita STS | true |
|
|
114
|
+
| AWS_LOCAL_SIMULATOR_ECS | Habilita ECS/Fargate | false |
|
|
115
|
+
| AWS_LOCAL_SIMULATOR_DYNAMODB_PORT | Porta DynamoDB | 8000 |
|
|
116
|
+
| AWS_LOCAL_SIMULATOR_S3_PORT | Porta S3 | 4566 |
|
|
117
|
+
| AWS_LOCAL_SIMULATOR_SQS_PORT | Porta SQS | 9324 |
|
|
118
|
+
| AWS_LOCAL_SIMULATOR_LAMBDA_PORT | Porta Lambda | 3001 |
|
|
119
|
+
| AWS_LOCAL_SIMULATOR_COGNITO_PORT | Porta Cognito | 9229 |
|
|
120
|
+
| AWS_LOCAL_SIMULATOR_APIGATEWAY_PORT | Porta API Gateway | 4567 |
|
|
121
|
+
| AWS_LOCAL_SIMULATOR_STS_PORT | Porta STS | 9326 |
|
|
122
|
+
| AWS_LOCAL_SIMULATOR_ECS_PORT | Porta ECS | 8080 |
|
|
123
|
+
| AWS_LOCAL_SIMULATOR_DATA | Diretório de dados | ./aws-local-simulator-data |
|
|
124
|
+
| AWS_LOCAL_SIMULATOR_LOG | Nível de log | info |
|
|
125
|
+
|
|
126
|
+
## 📝 Comandos CLI
|
|
119
127
|
|
|
120
|
-
# 📝 Comandos CLI
|
|
121
128
|
```bash
|
|
122
|
-
|
|
129
|
+
# Iniciar simulador
|
|
123
130
|
npx aws-local-simulator start [configPath]
|
|
124
131
|
|
|
125
|
-
|
|
132
|
+
# Parar simulador
|
|
126
133
|
npx aws-local-simulator stop
|
|
127
134
|
|
|
128
|
-
|
|
135
|
+
# Reiniciar
|
|
129
136
|
npx aws-local-simulator restart
|
|
130
137
|
|
|
131
|
-
|
|
138
|
+
# Resetar dados
|
|
132
139
|
npx aws-local-simulator reset
|
|
133
140
|
|
|
134
|
-
|
|
141
|
+
# Status
|
|
135
142
|
npx aws-local-simulator status
|
|
136
143
|
```
|
|
137
144
|
|
|
138
|
-
|
|
145
|
+
## 🔌 Endpoints
|
|
146
|
+
|
|
139
147
|
| Serviço | Endpoint | Admin |
|
|
140
148
|
|---------|----------|-------|
|
|
141
|
-
| DynamoDB | http://localhost:8000
|
|
142
|
-
| S3 | http://localhost:4566
|
|
143
|
-
| SQS | http://localhost:9324
|
|
144
|
-
| Lambda | http://localhost:3001
|
|
145
|
-
| Cognito | http://localhost:9229
|
|
146
|
-
| API Gateway | http://localhost:4567
|
|
147
|
-
|
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
| DynamoDB | http://localhost:8000 | http://localhost:8000/__admin/tables |
|
|
150
|
+
| S3 | http://localhost:4566 | http://localhost:4566/__admin/buckets |
|
|
151
|
+
| SQS | http://localhost:9324 | http://localhost:9324/__admin/queues |
|
|
152
|
+
| Lambda | http://localhost:3001 | http://localhost:3001/__admin/functions |
|
|
153
|
+
| Cognito | http://localhost:9229 | http://localhost:9229/__admin/userpools |
|
|
154
|
+
| API Gateway | http://localhost:4567 | http://localhost:4567/__admin/apis |
|
|
155
|
+
| STS | http://localhost:9326 | — |
|
|
156
|
+
| ECS | http://localhost:8080 | http://localhost:8080/__admin/clusters |
|
|
157
|
+
|
|
158
|
+
## 🧪 Testando com AWS CLI
|
|
159
|
+
|
|
150
160
|
```bash
|
|
151
161
|
# DynamoDB
|
|
152
162
|
aws dynamodb list-tables --endpoint-url http://localhost:8000
|
|
@@ -157,14 +167,59 @@ aws s3 ls --endpoint-url http://localhost:4566
|
|
|
157
167
|
# SQS
|
|
158
168
|
aws sqs list-queues --endpoint-url http://localhost:9324
|
|
159
169
|
|
|
170
|
+
# Lambda — invocar por nome (não por path HTTP)
|
|
171
|
+
aws lambda invoke \
|
|
172
|
+
--function-name my-function \
|
|
173
|
+
--payload '{"key":"value"}' \
|
|
174
|
+
--endpoint-url http://localhost:3001 \
|
|
175
|
+
output.json
|
|
176
|
+
|
|
160
177
|
# Cognito
|
|
161
178
|
aws cognito-idp list-user-pools --max-results 10 --endpoint-url http://localhost:9229
|
|
162
179
|
|
|
180
|
+
# STS
|
|
181
|
+
aws sts get-caller-identity --endpoint-url http://localhost:9326
|
|
182
|
+
aws sts assume-role \
|
|
183
|
+
--role-arn "arn:aws:iam::123456789012:role/my-role" \
|
|
184
|
+
--role-session-name "my-session" \
|
|
185
|
+
--endpoint-url http://localhost:9326
|
|
186
|
+
|
|
163
187
|
# API Gateway
|
|
164
188
|
aws apigateway get-rest-apis --endpoint-url http://localhost:4567
|
|
165
189
|
```
|
|
166
190
|
|
|
167
|
-
|
|
191
|
+
## ⚙️ Configuração de Lambdas
|
|
192
|
+
|
|
193
|
+
Lambdas são registradas por **nome** e invocadas via API de invocação (igual à AWS real). O roteamento HTTP é feito pelo API Gateway.
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"lambdas": [
|
|
198
|
+
{
|
|
199
|
+
"name": "my-function",
|
|
200
|
+
"handler": "./src/handlers/my-function.js",
|
|
201
|
+
"env": {
|
|
202
|
+
"TABLE_NAME": "users-table",
|
|
203
|
+
"BUCKET_NAME": "my-bucket"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
O handler deve exportar uma função padrão:
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
exports.handler = async (event, context) => {
|
|
214
|
+
return {
|
|
215
|
+
statusCode: 200,
|
|
216
|
+
body: JSON.stringify({ message: 'Hello from Lambda!' })
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 📁 Estrutura de Dados
|
|
222
|
+
|
|
168
223
|
Os dados são persistidos em:
|
|
169
224
|
|
|
170
225
|
```text
|
|
@@ -177,28 +232,26 @@ Os dados são persistidos em:
|
|
|
177
232
|
└── ecs/
|
|
178
233
|
```
|
|
179
234
|
|
|
180
|
-
🐛 Debug
|
|
181
|
-
Para logs detalhados:
|
|
235
|
+
## 🐛 Debug
|
|
182
236
|
|
|
183
|
-
bash
|
|
237
|
+
```bash
|
|
184
238
|
AWS_LOCAL_SIMULATOR_LOG=verboso npx aws-local-simulator start
|
|
185
|
-
|
|
186
|
-
Fork o projeto
|
|
187
|
-
|
|
188
|
-
Crie sua feature branch (git checkout -b feature/AmazingFeature)
|
|
239
|
+
```
|
|
189
240
|
|
|
190
|
-
|
|
241
|
+
## 🤝 Contribuindo
|
|
191
242
|
|
|
192
|
-
|
|
243
|
+
1. Fork o projeto
|
|
244
|
+
2. Crie sua feature branch (`git checkout -b feature/AmazingFeature`)
|
|
245
|
+
3. Commit suas mudanças (`git commit -m 'Add some AmazingFeature'`)
|
|
246
|
+
4. Push para a branch (`git push origin feature/AmazingFeature`)
|
|
247
|
+
5. Abra um Pull Request
|
|
193
248
|
|
|
194
|
-
|
|
249
|
+
## 📄 Licença
|
|
195
250
|
|
|
196
|
-
📄 Licença
|
|
197
251
|
MIT © Luiz Gustavo Ribeiro
|
|
198
252
|
|
|
199
|
-
⚠️ Limitações
|
|
200
|
-
SNS e EventBridge em desenvolvimento
|
|
201
|
-
|
|
202
|
-
WebSocket APIs em desenvolvimento
|
|
253
|
+
## ⚠️ Limitações
|
|
203
254
|
|
|
204
|
-
|
|
255
|
+
- SNS e EventBridge em desenvolvimento
|
|
256
|
+
- WebSocket APIs em desenvolvimento
|
|
257
|
+
- Para uso em desenvolvimento e testes apenas
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gugananuvem/aws-local-simulator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Simulador local completo para serviços AWS",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -109,6 +109,6 @@
|
|
|
109
109
|
"optional": true
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
|
-
"buildDate": "2026-04-
|
|
112
|
+
"buildDate": "2026-04-04T03:21:21.370Z",
|
|
113
113
|
"published": true
|
|
114
114
|
}
|
|
@@ -23,6 +23,7 @@ class ConfigLoader {
|
|
|
23
23
|
if (configPath) {
|
|
24
24
|
const userConfig = await this.loadUserConfig(configPath);
|
|
25
25
|
config = this.mergeDeep(config, userConfig);
|
|
26
|
+
config._configPath = path.resolve(process.cwd(), configPath);
|
|
26
27
|
} else {
|
|
27
28
|
// Tenta encontrar arquivo de configuração padrão
|
|
28
29
|
const possiblePaths = [
|
|
@@ -35,6 +36,7 @@ class ConfigLoader {
|
|
|
35
36
|
if (fs.existsSync(possiblePath)) {
|
|
36
37
|
const userConfig = await this.loadUserConfig(possiblePath);
|
|
37
38
|
config = this.mergeDeep(config, userConfig);
|
|
39
|
+
config._configPath = possiblePath;
|
|
38
40
|
logger.info(`✅ Configuração carregada de: ${possiblePath}`);
|
|
39
41
|
break;
|
|
40
42
|
}
|
|
@@ -14,6 +14,7 @@ module.exports = {
|
|
|
14
14
|
ecs: false,
|
|
15
15
|
cognito: false,
|
|
16
16
|
apigateway: false,
|
|
17
|
+
sts: true,
|
|
17
18
|
},
|
|
18
19
|
|
|
19
20
|
// Portas padrão
|
|
@@ -27,6 +28,7 @@ module.exports = {
|
|
|
27
28
|
ecs: 8080,
|
|
28
29
|
cognito: 9229,
|
|
29
30
|
apigateway: 4567,
|
|
31
|
+
sts: 9326,
|
|
30
32
|
},
|
|
31
33
|
apigateway: {
|
|
32
34
|
defaultCors: {
|
package/src/server.js
CHANGED
|
@@ -17,6 +17,7 @@ const EventBridgeService = require("./services/eventbridge");
|
|
|
17
17
|
const CognitoService = require("./services/cognito");
|
|
18
18
|
const APIGatewayService = require("./services/apigateway");
|
|
19
19
|
const ECSService = require("./services/ecs");
|
|
20
|
+
const STSService = require("./services/sts");
|
|
20
21
|
|
|
21
22
|
class Server {
|
|
22
23
|
constructor(config) {
|
|
@@ -65,6 +66,7 @@ class Server {
|
|
|
65
66
|
async initializeServices() {
|
|
66
67
|
// Ordem de inicialização importante
|
|
67
68
|
const serviceOrder = [
|
|
69
|
+
{ name: "sts", class: STSService, depends: [] },
|
|
68
70
|
{ name: "lambda", class: LambdaService, depends: [] },
|
|
69
71
|
{ name: "dynamodb", class: DynamoDBService, depends: [] },
|
|
70
72
|
{ name: "s3", class: S3Service, depends: [] },
|
|
@@ -73,7 +75,7 @@ class Server {
|
|
|
73
75
|
{ name: "eventbridge", class: EventBridgeService, depends: [] },
|
|
74
76
|
{ name: "cognito", class: CognitoService, depends: [] },
|
|
75
77
|
{ name: "ecs", class: ECSService, depends: [] },
|
|
76
|
-
{ name: "apigateway", class: APIGatewayService, depends: [] },
|
|
78
|
+
{ name: "apigateway", class: APIGatewayService, depends: ["lambda"] },
|
|
77
79
|
];
|
|
78
80
|
|
|
79
81
|
for (const serviceDef of serviceOrder) {
|
|
@@ -7,24 +7,26 @@ const APIGatewayServer = require('./server');
|
|
|
7
7
|
const APIGatewaySimulator = require('./simulator');
|
|
8
8
|
|
|
9
9
|
class APIGatewayService {
|
|
10
|
-
constructor(config) {
|
|
10
|
+
constructor(config, dependencies = {}) {
|
|
11
11
|
this.config = config;
|
|
12
12
|
this.name = 'apigateway';
|
|
13
13
|
this.port = config.ports.apigateway || 4567;
|
|
14
14
|
this.server = null;
|
|
15
15
|
this.simulator = null;
|
|
16
16
|
this.isRunning = false;
|
|
17
|
+
this.lambdaService = dependencies.lambda || null;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
async initialize() {
|
|
20
21
|
const logger = require('../../utils/logger');
|
|
21
22
|
logger.debug(`Inicializando API Gateway Service na porta ${this.port}...`);
|
|
22
|
-
|
|
23
|
+
|
|
23
24
|
this.simulator = new APIGatewaySimulator(this.config);
|
|
24
25
|
await this.simulator.initialize();
|
|
25
|
-
|
|
26
|
+
|
|
26
27
|
this.server = new APIGatewayServer(this.port, this.config);
|
|
27
28
|
this.server.simulator = this.simulator;
|
|
29
|
+
this.server.lambdaService = this.lambdaService;
|
|
28
30
|
|
|
29
31
|
await this.server.initialize();
|
|
30
32
|
|
|
@@ -35,10 +35,63 @@ class APIGatewayServer {
|
|
|
35
35
|
|
|
36
36
|
async initialize() {
|
|
37
37
|
this.setupRoutes();
|
|
38
|
+
this.setupConfigRoutes();
|
|
38
39
|
this.setupProxyRoutes();
|
|
39
40
|
logger.debug('API Gateway Server inicializado');
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
setupConfigRoutes() {
|
|
44
|
+
// Register routes from aws-local-simulator.json config directly
|
|
45
|
+
const apis = this.config.apigateway?.apis || [];
|
|
46
|
+
for (const api of apis) {
|
|
47
|
+
for (const endpoint of (api.endpoints || [])) {
|
|
48
|
+
const { path, method, lambdaName, integrationType } = endpoint;
|
|
49
|
+
if (!path || !method) continue;
|
|
50
|
+
|
|
51
|
+
const expressPath = path.replace(/\{([^}]+)\}/g, ':$1');
|
|
52
|
+
const httpMethod = method.toLowerCase();
|
|
53
|
+
|
|
54
|
+
logger.debug(`📡 Registrando rota: ${method} ${path} -> ${lambdaName}`);
|
|
55
|
+
|
|
56
|
+
this.app[httpMethod](expressPath, async (req, res) => {
|
|
57
|
+
try {
|
|
58
|
+
const lambdaService = this.lambdaService;
|
|
59
|
+
if (!lambdaService) {
|
|
60
|
+
return res.status(500).json({ error: 'Lambda service not available' });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const event = {
|
|
64
|
+
httpMethod: req.method,
|
|
65
|
+
path: req.path,
|
|
66
|
+
headers: req.headers,
|
|
67
|
+
queryStringParameters: Object.keys(req.query).length ? req.query : null,
|
|
68
|
+
pathParameters: Object.keys(req.params).length ? req.params : null,
|
|
69
|
+
body: req.body ? JSON.stringify(req.body) : null,
|
|
70
|
+
isBase64Encoded: false,
|
|
71
|
+
requestContext: {
|
|
72
|
+
path: req.path,
|
|
73
|
+
stage: 'local',
|
|
74
|
+
requestId: Math.random().toString(36).substring(7),
|
|
75
|
+
identity: { sourceIp: req.ip }
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const result = await lambdaService.simulator.invoke(lambdaName, event);
|
|
80
|
+
const payload = result.Payload || {};
|
|
81
|
+
const statusCode = payload.statusCode || 200;
|
|
82
|
+
const headers = payload.headers || { 'Content-Type': 'application/json' };
|
|
83
|
+
const body = payload.body;
|
|
84
|
+
|
|
85
|
+
res.status(statusCode).set(headers).send(body);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
logger.error(`Lambda invoke error (${lambdaName}):`, err);
|
|
88
|
+
res.status(500).json({ error: err.message });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
42
95
|
setupRoutes() {
|
|
43
96
|
// Health check
|
|
44
97
|
this.app.get('/health', (req, res) => {
|
|
@@ -16,7 +16,19 @@ class CognitoServer {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
setupMiddlewares() {
|
|
19
|
-
this.app.use(express.
|
|
19
|
+
this.app.use(express.raw({ type: '*/*', limit: '10mb' }));
|
|
20
|
+
this.app.use((req, res, next) => {
|
|
21
|
+
if (req.body && Buffer.isBuffer(req.body)) {
|
|
22
|
+
try {
|
|
23
|
+
req.body = JSON.parse(req.body.toString('utf8'));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
req.body = {};
|
|
26
|
+
}
|
|
27
|
+
} else if (!req.body) {
|
|
28
|
+
req.body = {};
|
|
29
|
+
}
|
|
30
|
+
next();
|
|
31
|
+
});
|
|
20
32
|
|
|
21
33
|
if (logger.currentLogLevel === 'verboso') {
|
|
22
34
|
this.app.use((req, res, next) => {
|
|
@@ -48,12 +60,13 @@ class CognitoServer {
|
|
|
48
60
|
// User Pool operations
|
|
49
61
|
this.app.post('/', async (req, res) => {
|
|
50
62
|
const target = req.headers['x-amz-target'];
|
|
63
|
+
logger.info(`Cognito incoming: target=${target} body=${JSON.stringify(req.body)}`);
|
|
51
64
|
if (!target) {
|
|
52
65
|
return res.status(400).json({ error: 'Missing X-Amz-Target header' });
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
try {
|
|
56
|
-
const result = await this.handleRequest(target, req.body);
|
|
69
|
+
const result = await this.handleRequest(target, req.body || {});
|
|
57
70
|
res.json(result);
|
|
58
71
|
} catch (error) {
|
|
59
72
|
logger.error('Cognito Error:', error);
|
|
@@ -84,20 +97,46 @@ class CognitoServer {
|
|
|
84
97
|
case 'DeleteUserPool':
|
|
85
98
|
return this.simulator.deleteUserPool(params);
|
|
86
99
|
|
|
100
|
+
case 'ListUsers':
|
|
101
|
+
return this.simulator.listUsers(params);
|
|
87
102
|
// User Pool Client Management
|
|
88
103
|
case 'CreateUserPoolClient':
|
|
89
104
|
return this.simulator.createUserPoolClient(params);
|
|
105
|
+
case 'ListUserPoolClients':
|
|
106
|
+
return this.simulator.listUserPoolClients(params);
|
|
107
|
+
case 'DescribeUserPoolClient':
|
|
108
|
+
return this.simulator.describeUserPoolClient(params);
|
|
109
|
+
case 'DeleteUserPoolClient':
|
|
110
|
+
return this.simulator.deleteUserPoolClient(params);
|
|
90
111
|
|
|
91
112
|
// User Operations
|
|
92
113
|
case 'SignUp':
|
|
93
114
|
return this.simulator.signUp(params);
|
|
94
115
|
case 'ConfirmSignUp':
|
|
95
116
|
return this.simulator.confirmSignUp(params);
|
|
117
|
+
case 'ForgotPassword':
|
|
118
|
+
return this.simulator.forgotPassword(params);
|
|
119
|
+
case 'ConfirmForgotPassword':
|
|
120
|
+
return this.simulator.confirmForgotPassword(params);
|
|
121
|
+
case 'ChangePassword':
|
|
122
|
+
return this.simulator.changePassword(params);
|
|
96
123
|
case 'InitiateAuth':
|
|
97
124
|
return this.simulator.initiateAuth(params);
|
|
125
|
+
case 'RespondToAuthChallenge':
|
|
126
|
+
return this.simulator.respondToAuthChallenge(params);
|
|
98
127
|
case 'GetToken':
|
|
99
128
|
return this.simulator.getToken(params);
|
|
100
|
-
|
|
129
|
+
case 'GlobalSignOut':
|
|
130
|
+
return this.simulator.globalSignOut(params);
|
|
131
|
+
case 'RevokeToken':
|
|
132
|
+
return this.simulator.revokeToken(params);
|
|
133
|
+
case 'GetUser':
|
|
134
|
+
return this.simulator.getUser(params);
|
|
135
|
+
case 'UpdateUserAttributes':
|
|
136
|
+
return this.simulator.updateUserAttributes(params);
|
|
137
|
+
case 'DeleteUser':
|
|
138
|
+
return this.simulator.deleteUser(params);
|
|
139
|
+
|
|
101
140
|
// Admin Operations
|
|
102
141
|
case 'AdminGetUser':
|
|
103
142
|
return this.simulator.adminGetUser(params);
|
|
@@ -107,6 +146,18 @@ class CognitoServer {
|
|
|
107
146
|
return this.simulator.adminSetUserPassword(params);
|
|
108
147
|
case 'AdminDeleteUser':
|
|
109
148
|
return this.simulator.adminDeleteUser(params);
|
|
149
|
+
case 'AdminDisableUser':
|
|
150
|
+
return this.simulator.adminDisableUser(params);
|
|
151
|
+
case 'AdminEnableUser':
|
|
152
|
+
return this.simulator.adminEnableUser(params);
|
|
153
|
+
case 'AdminResetUserPassword':
|
|
154
|
+
return this.simulator.adminResetUserPassword(params);
|
|
155
|
+
case 'AdminInitiateAuth':
|
|
156
|
+
return this.simulator.initiateAuth(params);
|
|
157
|
+
case 'AdminListGroupsForUser':
|
|
158
|
+
return this.simulator.adminListGroupsForUser(params);
|
|
159
|
+
case 'AdminUserGlobalSignOut':
|
|
160
|
+
return this.simulator.adminUserGlobalSignOut(params);
|
|
110
161
|
|
|
111
162
|
// Identity Pool Operations
|
|
112
163
|
case 'CreateIdentityPool':
|