kybernus 2.1.1 → 2.2.1
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/package.json +2 -2
- package/templates/java-spring/clean/infra/main.tf.hbs +42 -18
- package/templates/java-spring/clean/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/java-spring/clean/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/java-spring/clean/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/java-spring/hexagonal/infra/main.tf.hbs +42 -18
- package/templates/java-spring/hexagonal/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/java-spring/hexagonal/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/java-spring/hexagonal/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/java-spring/mvc/infra/main.tf.hbs +42 -18
- package/templates/java-spring/mvc/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/java-spring/mvc/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/java-spring/mvc/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/AuthController.java.hbs +38 -42
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/ItemController.java.hbs +42 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/PaymentsController.java.hbs +65 -22
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/model/Item.java.hbs +38 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/model/User.java.hbs +41 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/repository/ItemRepository.java.hbs +9 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/repository/UserRepository.java.hbs +13 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/service/AuthService.java.hbs +62 -0
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/service/StripeService.java.hbs +18 -18
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/{{projectNamePascalCase}}Application.java.hbs +2 -0
- package/templates/nestjs/clean/infra/main.tf.hbs +42 -18
- package/templates/nestjs/clean/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nestjs/clean/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nestjs/clean/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nestjs/hexagonal/infra/main.tf.hbs +42 -18
- package/templates/nestjs/hexagonal/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nestjs/hexagonal/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nestjs/hexagonal/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nestjs/mvc/infra/main.tf.hbs +42 -18
- package/templates/nestjs/mvc/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nestjs/mvc/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nestjs/mvc/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nestjs/mvc/package.json.hbs +6 -2
- package/templates/nestjs/mvc/prisma/schema.prisma.hbs +31 -0
- package/templates/nestjs/mvc/src/app.module.ts.hbs +3 -1
- package/templates/nestjs/mvc/src/auth/auth.service.ts.hbs +34 -31
- package/templates/nestjs/mvc/src/payments/payments.service.ts.hbs +26 -6
- package/templates/nestjs/mvc/src/prisma/prisma.module.ts.hbs +9 -0
- package/templates/nestjs/mvc/src/prisma/prisma.service.ts.hbs +15 -0
- package/templates/nestjs/mvc/src/services/items.service.ts.hbs +33 -20
- package/templates/nextjs/mvc/infra/main.tf.hbs +42 -18
- package/templates/nextjs/mvc/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nextjs/mvc/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nextjs/mvc/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nextjs/mvc/package.json.hbs +1 -0
- package/templates/nextjs/mvc/prisma/schema.prisma.hbs +60 -6
- package/templates/nextjs/mvc/src/app/api/webhook/route.ts.hbs +23 -18
- package/templates/nodejs-express/clean/infra/main.tf.hbs +42 -18
- package/templates/nodejs-express/clean/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nodejs-express/clean/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nodejs-express/clean/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nodejs-express/hexagonal/infra/main.tf.hbs +42 -18
- package/templates/nodejs-express/hexagonal/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nodejs-express/hexagonal/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nodejs-express/hexagonal/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nodejs-express/mvc/infra/main.tf.hbs +42 -18
- package/templates/nodejs-express/mvc/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/nodejs-express/mvc/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/nodejs-express/mvc/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/nodejs-express/mvc/package.json.hbs +8 -4
- package/templates/nodejs-express/mvc/prisma/schema.prisma.hbs +31 -0
- package/templates/nodejs-express/mvc/src/config/database.ts.hbs +2 -9
- package/templates/nodejs-express/mvc/src/controllers/auth.controller.ts.hbs +40 -58
- package/templates/nodejs-express/mvc/src/controllers/items.controller.ts.hbs +29 -0
- package/templates/nodejs-express/mvc/src/models/README.md.hbs +10 -0
- package/templates/nodejs-express/mvc/src/prisma/client.ts.hbs +3 -0
- package/templates/nodejs-express/mvc/src/services/auth.service.ts.hbs +71 -0
- package/templates/nodejs-express/mvc/src/services/stripe.service.ts.hbs +35 -25
- package/templates/python-fastapi/clean/infra/main.tf.hbs +42 -18
- package/templates/python-fastapi/clean/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/python-fastapi/clean/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/python-fastapi/clean/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/python-fastapi/hexagonal/infra/main.tf.hbs +42 -18
- package/templates/python-fastapi/hexagonal/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/python-fastapi/hexagonal/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/python-fastapi/hexagonal/infra/modules/vpc/main.tf.hbs +170 -30
- package/templates/python-fastapi/mvc/app/controllers/auth.py.hbs +25 -16
- package/templates/python-fastapi/mvc/app/controllers/items.py.hbs +9 -7
- package/templates/python-fastapi/mvc/app/controllers/payments.py.hbs +42 -15
- package/templates/python-fastapi/mvc/app/database.py.hbs +17 -0
- package/templates/python-fastapi/mvc/app/main.py.hbs +4 -0
- package/templates/python-fastapi/mvc/app/models/item.py.hbs +11 -8
- package/templates/python-fastapi/mvc/app/models/user.py.hbs +15 -0
- package/templates/python-fastapi/mvc/app/repositories/item_repository.py.hbs +15 -0
- package/templates/python-fastapi/mvc/app/repositories/user_repository.py.hbs +15 -0
- package/templates/python-fastapi/mvc/app/services/item_service.py.hbs +17 -19
- package/templates/python-fastapi/mvc/infra/main.tf.hbs +42 -18
- package/templates/python-fastapi/mvc/infra/modules/ecs/main.tf.hbs +217 -6
- package/templates/python-fastapi/mvc/infra/modules/rds/main.tf.hbs +15 -15
- package/templates/python-fastapi/mvc/infra/modules/vpc/main.tf.hbs +170 -30
|
@@ -10,81 +10,213 @@ variable "environment" {
|
|
|
10
10
|
|
|
11
11
|
# VPC
|
|
12
12
|
resource "aws_vpc" "main" {
|
|
13
|
-
cidr_block
|
|
13
|
+
cidr_block = "10.0.0.0/16"
|
|
14
14
|
enable_dns_hostnames = true
|
|
15
|
-
enable_dns_support
|
|
15
|
+
enable_dns_support = true
|
|
16
16
|
|
|
17
17
|
tags = {
|
|
18
|
-
Name
|
|
18
|
+
Name = "${var.app_name}-${var.environment}-vpc"
|
|
19
19
|
Environment = var.environment
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
# Internet Gateway
|
|
24
|
+
resource "aws_internet_gateway" "main" {
|
|
25
|
+
vpc_id = aws_vpc.main.id
|
|
26
|
+
|
|
27
|
+
tags = {
|
|
28
|
+
Name = "${var.app_name}-${var.environment}-igw"
|
|
29
|
+
Environment = var.environment
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Data source for AZs
|
|
34
|
+
data "aws_availability_zones" "available" {
|
|
35
|
+
state = "available"
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
# Public Subnets
|
|
24
39
|
resource "aws_subnet" "public" {
|
|
25
|
-
count
|
|
40
|
+
count = 2
|
|
41
|
+
vpc_id = aws_vpc.main.id
|
|
42
|
+
cidr_block = "10.0.${count.index + 1}.0/24"
|
|
43
|
+
availability_zone = data.aws_availability_zones.available.names[count.index]
|
|
44
|
+
map_public_ip_on_launch = true
|
|
45
|
+
|
|
46
|
+
tags = {
|
|
47
|
+
Name = "${var.app_name}-${var.environment}-public-${count.index + 1}"
|
|
48
|
+
Environment = var.environment
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Route Table for Public Subnets
|
|
53
|
+
resource "aws_route_table" "public" {
|
|
26
54
|
vpc_id = aws_vpc.main.id
|
|
27
|
-
cidr_block = "10.0.${count.index + 1}.0/24"
|
|
28
|
-
availability_zone = data.aws_availability_zones.available.names[count.index]
|
|
29
55
|
|
|
30
|
-
|
|
56
|
+
route {
|
|
57
|
+
cidr_block = "0.0.0.0/0"
|
|
58
|
+
gateway_id = aws_internet_gateway.main.id
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
tags = {
|
|
62
|
+
Name = "${var.app_name}-${var.environment}-public-rt"
|
|
63
|
+
Environment = var.environment
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Association for Public Subnets
|
|
68
|
+
resource "aws_route_table_association" "public" {
|
|
69
|
+
count = 2
|
|
70
|
+
subnet_id = aws_subnet.public[count.index].id
|
|
71
|
+
route_table_id = aws_route_table.public.id
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Elastic IP for NAT Gateway
|
|
75
|
+
resource "aws_eip" "nat" {
|
|
76
|
+
count = 1
|
|
77
|
+
domain = "vpc"
|
|
31
78
|
|
|
32
79
|
tags = {
|
|
33
|
-
Name
|
|
80
|
+
Name = "${var.app_name}-${var.environment}-nat-eip"
|
|
81
|
+
Environment = var.environment
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# NAT Gateway (single NAT for cost savings, can change to 1 per AZ for production if needed)
|
|
86
|
+
resource "aws_nat_gateway" "main" {
|
|
87
|
+
count = 1
|
|
88
|
+
allocation_id = aws_eip.nat[0].id
|
|
89
|
+
subnet_id = aws_subnet.public[0].id
|
|
90
|
+
|
|
91
|
+
depends_on = [aws_internet_gateway.main]
|
|
92
|
+
|
|
93
|
+
tags = {
|
|
94
|
+
Name = "${var.app_name}-${var.environment}-nat"
|
|
34
95
|
Environment = var.environment
|
|
35
96
|
}
|
|
36
97
|
}
|
|
37
98
|
|
|
38
99
|
# Private Subnets
|
|
39
100
|
resource "aws_subnet" "private" {
|
|
40
|
-
count
|
|
41
|
-
vpc_id
|
|
42
|
-
cidr_block
|
|
101
|
+
count = 2
|
|
102
|
+
vpc_id = aws_vpc.main.id
|
|
103
|
+
cidr_block = "10.0.${count.index + 10}.0/24"
|
|
43
104
|
availability_zone = data.aws_availability_zones.available.names[count.index]
|
|
44
105
|
|
|
45
106
|
tags = {
|
|
46
|
-
Name
|
|
107
|
+
Name = "${var.app_name}-${var.environment}-private-${count.index + 1}"
|
|
47
108
|
Environment = var.environment
|
|
48
109
|
}
|
|
49
110
|
}
|
|
50
111
|
|
|
51
|
-
#
|
|
52
|
-
resource "
|
|
112
|
+
# Route Table for Private Subnets
|
|
113
|
+
resource "aws_route_table" "private" {
|
|
53
114
|
vpc_id = aws_vpc.main.id
|
|
54
115
|
|
|
116
|
+
route {
|
|
117
|
+
cidr_block = "0.0.0.0/0"
|
|
118
|
+
nat_gateway_id = aws_nat_gateway.main[0].id
|
|
119
|
+
}
|
|
120
|
+
|
|
55
121
|
tags = {
|
|
56
|
-
Name
|
|
122
|
+
Name = "${var.app_name}-${var.environment}-private-rt"
|
|
57
123
|
Environment = var.environment
|
|
58
124
|
}
|
|
59
125
|
}
|
|
60
126
|
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
127
|
+
# Association for Private Subnets
|
|
128
|
+
resource "aws_route_table_association" "private" {
|
|
129
|
+
count = 2
|
|
130
|
+
subnet_id = aws_subnet.private[count.index].id
|
|
131
|
+
route_table_id = aws_route_table.private.id
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Security Group for Load Balancer (ALB)
|
|
135
|
+
resource "aws_security_group" "alb" {
|
|
136
|
+
name = "${var.app_name}-${var.environment}-alb-sg"
|
|
137
|
+
description = "Security group for ALB"
|
|
138
|
+
vpc_id = aws_vpc.main.id
|
|
139
|
+
|
|
140
|
+
ingress {
|
|
141
|
+
from_port = 80
|
|
142
|
+
to_port = 80
|
|
143
|
+
protocol = "tcp"
|
|
144
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
145
|
+
description = "Allow HTTP from anywhere"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
ingress {
|
|
149
|
+
from_port = 443
|
|
150
|
+
to_port = 443
|
|
151
|
+
protocol = "tcp"
|
|
152
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
153
|
+
description = "Allow HTTPS from anywhere"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
egress {
|
|
157
|
+
from_port = 0
|
|
158
|
+
to_port = 0
|
|
159
|
+
protocol = "-1"
|
|
160
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
tags = {
|
|
164
|
+
Name = "${var.app_name}-${var.environment}-alb-sg"
|
|
165
|
+
Environment = var.environment
|
|
166
|
+
}
|
|
64
167
|
}
|
|
65
168
|
|
|
66
|
-
# Security Group for
|
|
169
|
+
# Security Group for ECS Tasks
|
|
170
|
+
resource "aws_security_group" "ecs_tasks" {
|
|
171
|
+
name = "${var.app_name}-${var.environment}-ecs-tasks-sg"
|
|
172
|
+
description = "Security group for ECS tasks"
|
|
173
|
+
vpc_id = aws_vpc.main.id
|
|
174
|
+
|
|
175
|
+
ingress {
|
|
176
|
+
from_port = 0
|
|
177
|
+
to_port = 0
|
|
178
|
+
protocol = "-1"
|
|
179
|
+
security_groups = [aws_security_group.alb.id]
|
|
180
|
+
description = "Allow all traffic from ALB"
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
egress {
|
|
184
|
+
from_port = 0
|
|
185
|
+
to_port = 0
|
|
186
|
+
protocol = "-1"
|
|
187
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
188
|
+
description = "Allow all outbound traffic"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
tags = {
|
|
192
|
+
Name = "${var.app_name}-${var.environment}-ecs-tasks-sg"
|
|
193
|
+
Environment = var.environment
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# Security Group for Database (RDS)
|
|
67
198
|
resource "aws_security_group" "db" {
|
|
68
|
-
name
|
|
199
|
+
name = "${var.app_name}-${var.environment}-db-sg"
|
|
69
200
|
description = "Security group for database"
|
|
70
|
-
vpc_id
|
|
201
|
+
vpc_id = aws_vpc.main.id
|
|
71
202
|
|
|
72
203
|
ingress {
|
|
73
|
-
from_port
|
|
74
|
-
to_port
|
|
75
|
-
protocol
|
|
76
|
-
|
|
204
|
+
from_port = 5432
|
|
205
|
+
to_port = 5432
|
|
206
|
+
protocol = "tcp"
|
|
207
|
+
security_groups = [aws_security_group.ecs_tasks.id]
|
|
208
|
+
description = "Allow PostgreSQL access from ECS tasks"
|
|
77
209
|
}
|
|
78
210
|
|
|
79
211
|
egress {
|
|
80
|
-
from_port
|
|
81
|
-
to_port
|
|
82
|
-
protocol
|
|
212
|
+
from_port = 0
|
|
213
|
+
to_port = 0
|
|
214
|
+
protocol = "-1"
|
|
83
215
|
cidr_blocks = ["0.0.0.0/0"]
|
|
84
216
|
}
|
|
85
217
|
|
|
86
218
|
tags = {
|
|
87
|
-
Name
|
|
219
|
+
Name = "${var.app_name}-${var.environment}-db-sg"
|
|
88
220
|
Environment = var.environment
|
|
89
221
|
}
|
|
90
222
|
}
|
|
@@ -104,4 +236,12 @@ output "private_subnet_ids" {
|
|
|
104
236
|
|
|
105
237
|
output "db_security_group_id" {
|
|
106
238
|
value = aws_security_group.db.id
|
|
107
|
-
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
output "alb_security_group_id" {
|
|
242
|
+
value = aws_security_group.alb.id
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
output "ecs_tasks_security_group_id" {
|
|
246
|
+
value = aws_security_group.ecs_tasks.id
|
|
247
|
+
}
|
package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/AuthController.java.hbs
CHANGED
|
@@ -2,68 +2,64 @@ package {{packageName}}.controller;
|
|
|
2
2
|
|
|
3
3
|
import {{packageName}}.dto.AuthRequest;
|
|
4
4
|
import {{packageName}}.dto.AuthResponse;
|
|
5
|
-
import {{packageName}}.
|
|
5
|
+
import {{packageName}}.model.User;
|
|
6
|
+
import {{packageName}}.service.AuthService;
|
|
6
7
|
import org.springframework.http.ResponseEntity;
|
|
7
|
-
import org.springframework.
|
|
8
|
+
import org.springframework.http.HttpStatus;
|
|
8
9
|
import org.springframework.web.bind.annotation.*;
|
|
10
|
+
import org.springframework.security.core.context.SecurityContextHolder;
|
|
11
|
+
import org.springframework.security.core.Authentication;
|
|
9
12
|
|
|
10
|
-
import java.util.HashMap;
|
|
11
13
|
import java.util.Map;
|
|
12
|
-
import java.util.UUID;
|
|
13
14
|
|
|
14
15
|
@RestController
|
|
15
16
|
@RequestMapping("/api/auth")
|
|
16
17
|
public class AuthController {
|
|
17
18
|
|
|
18
|
-
private final
|
|
19
|
-
private final PasswordEncoder passwordEncoder;
|
|
19
|
+
private final AuthService authService;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
public AuthController(JwtTokenProvider tokenProvider, PasswordEncoder passwordEncoder) {
|
|
25
|
-
this.tokenProvider = tokenProvider;
|
|
26
|
-
this.passwordEncoder = passwordEncoder;
|
|
21
|
+
public AuthController(AuthService authService) {
|
|
22
|
+
this.authService = authService;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
@PostMapping("/register")
|
|
30
|
-
public ResponseEntity
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return ResponseEntity.
|
|
26
|
+
public ResponseEntity<?> register(@RequestBody AuthRequest request) {
|
|
27
|
+
try {
|
|
28
|
+
AuthResponse response = authService.register(request);
|
|
29
|
+
return ResponseEntity.ok(response);
|
|
30
|
+
} catch (IllegalArgumentException e) {
|
|
31
|
+
return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
String userId = UUID.randomUUID().toString();
|
|
37
|
-
String hashedPassword = passwordEncoder.encode(request.password());
|
|
38
|
-
|
|
39
|
-
users.put(request.email(), Map.of(
|
|
40
|
-
"id", userId,
|
|
41
|
-
"email", request.email(),
|
|
42
|
-
"password", hashedPassword
|
|
43
|
-
));
|
|
44
|
-
|
|
45
|
-
String token = tokenProvider.generateToken(userId, request.email());
|
|
46
|
-
|
|
47
|
-
return ResponseEntity.ok(new AuthResponse(token, userId, request.email()));
|
|
48
33
|
}
|
|
49
34
|
|
|
50
35
|
@PostMapping("/login")
|
|
51
36
|
public ResponseEntity<?> login(@RequestBody AuthRequest request) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
try {
|
|
38
|
+
AuthResponse response = authService.login(request);
|
|
39
|
+
return ResponseEntity.ok(response);
|
|
40
|
+
} catch (IllegalArgumentException e) {
|
|
41
|
+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("error", e.getMessage()));
|
|
56
42
|
}
|
|
57
|
-
|
|
58
|
-
String token = tokenProvider.generateToken(user.get("id"), user.get("email"));
|
|
59
|
-
|
|
60
|
-
return ResponseEntity.ok(new AuthResponse(token, user.get("id"), user.get("email")));
|
|
61
43
|
}
|
|
62
44
|
|
|
63
45
|
@GetMapping("/me")
|
|
64
|
-
public ResponseEntity
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
public ResponseEntity<?> me() {
|
|
47
|
+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
|
48
|
+
if (authentication == null || !authentication.isAuthenticated()) {
|
|
49
|
+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
String userId = (String) authentication.getPrincipal(); // Assuming custom jwt filter sets principal to id
|
|
54
|
+
User user = authService.getMe(userId);
|
|
55
|
+
return ResponseEntity.ok(Map.of(
|
|
56
|
+
"id", user.getId(),
|
|
57
|
+
"email", user.getEmail(),
|
|
58
|
+
"name", user.getName()
|
|
59
|
+
));
|
|
60
|
+
} catch (Exception e) {
|
|
61
|
+
// Keep original behavior if principal isn't id
|
|
62
|
+
return ResponseEntity.ok(Map.of("message", "Authenticated"));
|
|
63
|
+
}
|
|
68
64
|
}
|
|
69
|
-
}
|
|
65
|
+
}
|
package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/ItemController.java.hbs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package {{packageName}}.controller;
|
|
2
|
+
|
|
3
|
+
import {{packageName}}.model.Item;
|
|
4
|
+
import {{packageName}}.repository.ItemRepository;
|
|
5
|
+
import org.springframework.http.ResponseEntity;
|
|
6
|
+
import org.springframework.web.bind.annotation.*;
|
|
7
|
+
|
|
8
|
+
import java.util.List;
|
|
9
|
+
|
|
10
|
+
@RestController
|
|
11
|
+
@RequestMapping("/api/items")
|
|
12
|
+
public class ItemController {
|
|
13
|
+
|
|
14
|
+
private final ItemRepository itemRepository;
|
|
15
|
+
|
|
16
|
+
public ItemController(ItemRepository itemRepository) {
|
|
17
|
+
this.itemRepository = itemRepository;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@GetMapping
|
|
21
|
+
public List<Item> getAllItems() {
|
|
22
|
+
return itemRepository.findAll();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@PostMapping
|
|
26
|
+
public Item createItem(@RequestBody Item item) {
|
|
27
|
+
return itemRepository.save(item);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@GetMapping("/{id}")
|
|
31
|
+
public ResponseEntity<Item> getItem(@PathVariable String id) {
|
|
32
|
+
return itemRepository.findById(id)
|
|
33
|
+
.map(ResponseEntity::ok)
|
|
34
|
+
.orElse(ResponseEntity.notFound().build());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@DeleteMapping("/{id}")
|
|
38
|
+
public ResponseEntity<Void> deleteItem(@PathVariable String id) {
|
|
39
|
+
itemRepository.deleteById(id);
|
|
40
|
+
return ResponseEntity.ok().build();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,49 +1,92 @@
|
|
|
1
1
|
package {{packageName}}.controller;
|
|
2
2
|
|
|
3
|
+
import com.stripe.exception.SignatureVerificationException;
|
|
4
|
+
import com.stripe.model.Event;
|
|
5
|
+
import com.stripe.net.Webhook;
|
|
6
|
+
import {{packageName}}.model.User;
|
|
7
|
+
import {{packageName}}.repository.UserRepository;
|
|
3
8
|
import {{packageName}}.service.StripeService;
|
|
4
|
-
import
|
|
9
|
+
import org.slf4j.Logger;
|
|
10
|
+
import org.slf4j.LoggerFactory;
|
|
11
|
+
import org.springframework.beans.factory.annotation.Value;
|
|
12
|
+
import org.springframework.http.HttpStatus;
|
|
5
13
|
import org.springframework.http.ResponseEntity;
|
|
6
14
|
import org.springframework.web.bind.annotation.*;
|
|
7
15
|
|
|
8
16
|
import java.util.Map;
|
|
17
|
+
import java.util.Optional;
|
|
9
18
|
|
|
10
19
|
@RestController
|
|
11
20
|
@RequestMapping("/api/payments")
|
|
12
21
|
public class PaymentsController {
|
|
13
22
|
|
|
23
|
+
private static final Logger logger = LoggerFactory.getLogger(PaymentsController.class);
|
|
24
|
+
|
|
25
|
+
@Value("${stripe.webhook-secret}")
|
|
26
|
+
private String webhookSecret;
|
|
27
|
+
|
|
14
28
|
private final StripeService stripeService;
|
|
29
|
+
private final UserRepository userRepository;
|
|
15
30
|
|
|
16
|
-
public PaymentsController(StripeService stripeService) {
|
|
31
|
+
public PaymentsController(StripeService stripeService, UserRepository userRepository) {
|
|
17
32
|
this.stripeService = stripeService;
|
|
33
|
+
this.userRepository = userRepository;
|
|
18
34
|
}
|
|
19
35
|
|
|
20
36
|
@PostMapping("/checkout")
|
|
21
|
-
public ResponseEntity
|
|
22
|
-
<?> createCheckout(@RequestBody Map<String, String> request) {
|
|
37
|
+
public ResponseEntity<?> createCheckout(@RequestBody Map<String, String> request) {
|
|
23
38
|
try {
|
|
24
|
-
|
|
39
|
+
String customerId = request.get("customerId"); // Optional
|
|
40
|
+
com.stripe.model.checkout.Session session = stripeService.createCheckoutSession(customerId);
|
|
25
41
|
return ResponseEntity.ok(Map.of("url", session.getUrl()));
|
|
26
|
-
} catch (
|
|
27
|
-
|
|
42
|
+
} catch (Exception e) {
|
|
43
|
+
logger.error("Error creating checkout session", e);
|
|
44
|
+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
45
|
+
.body(Map.of("error", e.getMessage()));
|
|
28
46
|
}
|
|
29
47
|
}
|
|
30
48
|
|
|
31
|
-
@PostMapping("/
|
|
32
|
-
public ResponseEntity
|
|
49
|
+
@PostMapping("/webhook")
|
|
50
|
+
public ResponseEntity<String> handleWebhook(
|
|
51
|
+
@RequestBody String payload,
|
|
52
|
+
@RequestHeader("Stripe-Signature") String sigHeader) {
|
|
53
|
+
|
|
54
|
+
Event event;
|
|
55
|
+
|
|
33
56
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return ResponseEntity.status(
|
|
57
|
+
event = Webhook.constructEvent(payload, sigHeader, webhookSecret);
|
|
58
|
+
} catch (SignatureVerificationException e) {
|
|
59
|
+
logger.warn("Invalid signature", e);
|
|
60
|
+
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid signature");
|
|
61
|
+
} catch (Exception e) {
|
|
62
|
+
logger.error("Error parsing webhook", e);
|
|
63
|
+
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error parsing webhook");
|
|
38
64
|
}
|
|
39
|
-
}
|
|
40
65
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
66
|
+
switch (event.getType()) {
|
|
67
|
+
case "checkout.session.completed":
|
|
68
|
+
com.stripe.model.checkout.Session session = (com.stripe.model.checkout.Session) event.getDataObjectDeserializer().getObject().orElse(null);
|
|
69
|
+
if (session != null) {
|
|
70
|
+
logger.info("Checkout completed: {}", session.getId());
|
|
71
|
+
// Match to database user here using session properties
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case "customer.subscription.updated":
|
|
75
|
+
com.stripe.model.Subscription subscription = (com.stripe.model.Subscription) event.getDataObjectDeserializer().getObject().orElse(null);
|
|
76
|
+
if (subscription != null) {
|
|
77
|
+
logger.info("Subscription updated: {}", subscription.getId());
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
case "customer.subscription.deleted":
|
|
81
|
+
com.stripe.model.Subscription deletedSub = (com.stripe.model.Subscription) event.getDataObjectDeserializer().getObject().orElse(null);
|
|
82
|
+
if (deletedSub != null) {
|
|
83
|
+
logger.info("Subscription deleted: {}", deletedSub.getId());
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
logger.info("Unhandled event type: {}", event.getType());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return ResponseEntity.ok("Received");
|
|
48
91
|
}
|
|
49
|
-
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package {{packageName}}.model;
|
|
2
|
+
|
|
3
|
+
import jakarta.persistence.*;
|
|
4
|
+
import lombok.*;
|
|
5
|
+
import org.springframework.data.annotation.CreatedDate;
|
|
6
|
+
import org.springframework.data.annotation.LastModifiedDate;
|
|
7
|
+
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|
8
|
+
|
|
9
|
+
import java.time.LocalDateTime;
|
|
10
|
+
|
|
11
|
+
@Entity
|
|
12
|
+
@Table(name = "items")
|
|
13
|
+
@Data
|
|
14
|
+
@NoArgsConstructor
|
|
15
|
+
@AllArgsConstructor
|
|
16
|
+
@Builder
|
|
17
|
+
@EntityListeners(AuditingEntityListener.class)
|
|
18
|
+
public class Item {
|
|
19
|
+
|
|
20
|
+
@Id
|
|
21
|
+
@GeneratedValue(strategy = GenerationType.UUID)
|
|
22
|
+
private String id;
|
|
23
|
+
|
|
24
|
+
@Column(nullable = false)
|
|
25
|
+
private String name;
|
|
26
|
+
|
|
27
|
+
private String description;
|
|
28
|
+
|
|
29
|
+
private Double price;
|
|
30
|
+
|
|
31
|
+
@CreatedDate
|
|
32
|
+
@Column(name = "created_at", nullable = false, updatable = false)
|
|
33
|
+
private LocalDateTime createdAt;
|
|
34
|
+
|
|
35
|
+
@LastModifiedDate
|
|
36
|
+
@Column(name = "updated_at", nullable = false)
|
|
37
|
+
private LocalDateTime updatedAt;
|
|
38
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package {{packageName}}.model;
|
|
2
|
+
|
|
3
|
+
import jakarta.persistence.*;
|
|
4
|
+
import lombok.*;
|
|
5
|
+
import org.springframework.data.annotation.CreatedDate;
|
|
6
|
+
import org.springframework.data.annotation.LastModifiedDate;
|
|
7
|
+
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|
8
|
+
|
|
9
|
+
import java.time.LocalDateTime;
|
|
10
|
+
|
|
11
|
+
@Entity
|
|
12
|
+
@Table(name = "users")
|
|
13
|
+
@Data
|
|
14
|
+
@NoArgsConstructor
|
|
15
|
+
@AllArgsConstructor
|
|
16
|
+
@Builder
|
|
17
|
+
@EntityListeners(AuditingEntityListener.class)
|
|
18
|
+
public class User {
|
|
19
|
+
|
|
20
|
+
@Id
|
|
21
|
+
@GeneratedValue(strategy = GenerationType.UUID)
|
|
22
|
+
private String id;
|
|
23
|
+
|
|
24
|
+
@Column(unique = true, nullable = false)
|
|
25
|
+
private String email;
|
|
26
|
+
|
|
27
|
+
private String name;
|
|
28
|
+
|
|
29
|
+
private String password;
|
|
30
|
+
|
|
31
|
+
@Column(name = "stripe_customer_id")
|
|
32
|
+
private String stripeCustomerId;
|
|
33
|
+
|
|
34
|
+
@CreatedDate
|
|
35
|
+
@Column(name = "created_at", nullable = false, updatable = false)
|
|
36
|
+
private LocalDateTime createdAt;
|
|
37
|
+
|
|
38
|
+
@LastModifiedDate
|
|
39
|
+
@Column(name = "updated_at", nullable = false)
|
|
40
|
+
private LocalDateTime updatedAt;
|
|
41
|
+
}
|
package/templates/java-spring/mvc/src/main/java/{{packagePath}}/repository/ItemRepository.java.hbs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package {{packageName}}.repository;
|
|
2
|
+
|
|
3
|
+
import {{packageName}}.model.Item;
|
|
4
|
+
import org.springframework.data.jpa.repository.JpaRepository;
|
|
5
|
+
import org.springframework.stereotype.Repository;
|
|
6
|
+
|
|
7
|
+
@Repository
|
|
8
|
+
public interface ItemRepository extends JpaRepository<Item, String> {
|
|
9
|
+
}
|
package/templates/java-spring/mvc/src/main/java/{{packagePath}}/repository/UserRepository.java.hbs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package {{packageName}}.repository;
|
|
2
|
+
|
|
3
|
+
import {{packageName}}.model.User;
|
|
4
|
+
import org.springframework.data.jpa.repository.JpaRepository;
|
|
5
|
+
import org.springframework.stereotype.Repository;
|
|
6
|
+
|
|
7
|
+
import java.util.Optional;
|
|
8
|
+
|
|
9
|
+
@Repository
|
|
10
|
+
public interface UserRepository extends JpaRepository<User, String> {
|
|
11
|
+
Optional<User> findByEmail(String email);
|
|
12
|
+
Optional<User> findByStripeCustomerId(String stripeCustomerId);
|
|
13
|
+
}
|