express-genix 1.1.4 → 2.0.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.
- package/LICENSE +21 -0
- package/README.md +204 -259
- package/index.js +229 -113
- package/lib/cleanup.js +41 -129
- package/lib/features.js +239 -0
- package/lib/generator.js +286 -204
- package/lib/utils.js +43 -91
- package/package.json +81 -63
- package/templates/cicd/github-actions.yml.ejs +70 -0
- package/templates/config/database.mongo.js.ejs +29 -33
- package/templates/config/database.postgres.js.ejs +41 -40
- package/templates/config/database.prisma.js.ejs +26 -0
- package/templates/config/redis.js.ejs +28 -0
- package/templates/config/schema.prisma.ejs +20 -0
- package/templates/config/swagger.js.ejs +30 -0
- package/templates/config/websocket.js.ejs +62 -0
- package/templates/controllers/authController.js.ejs +152 -129
- package/templates/controllers/exampleController.js.ejs +92 -152
- package/templates/controllers/userController.js.ejs +52 -60
- package/templates/core/Dockerfile.ejs +41 -31
- package/templates/core/README.md.ejs +191 -179
- package/templates/core/app.js.ejs +114 -64
- package/templates/core/docker-compose.yml.ejs +59 -47
- package/templates/core/dockerignore.ejs +7 -0
- package/templates/core/env.ejs +25 -19
- package/templates/core/env.example.ejs +26 -0
- package/templates/core/eslintrc.json.ejs +50 -20
- package/templates/core/gitignore.ejs +51 -51
- package/templates/core/healthcheck.js.ejs +24 -24
- package/templates/core/jest.config.js.ejs +19 -22
- package/templates/core/package.json.ejs +70 -33
- package/templates/core/prettierrc.json.ejs +11 -11
- package/templates/core/server.js.ejs +64 -48
- package/templates/core/tsconfig.json.ejs +19 -0
- package/templates/middleware/auth.js.ejs +80 -66
- package/templates/middleware/cache.js.ejs +67 -0
- package/templates/middleware/errorHandler.js.ejs +50 -46
- package/templates/middleware/requestId.js.ejs +9 -0
- package/templates/middleware/validation.js.ejs +109 -47
- package/templates/migrations/create-users.js.ejs +50 -0
- package/templates/migrations/seed-users.js.ejs +34 -0
- package/templates/migrations/sequelizerc.ejs +8 -0
- package/templates/models/User.mongo.js.ejs +29 -29
- package/templates/models/User.postgres.js.ejs +40 -40
- package/templates/models/index.mongo.js.ejs +7 -7
- package/templates/models/index.postgres.js.ejs +11 -11
- package/templates/routes/authRoutes.js.ejs +222 -13
- package/templates/routes/exampleRoutes.js.ejs +100 -12
- package/templates/routes/index.js.ejs +34 -24
- package/templates/routes/userRoutes.js.ejs +78 -15
- package/templates/services/authService.js.ejs +111 -35
- package/templates/services/exampleService.js.ejs +112 -112
- package/templates/services/userService.mongodb.js.ejs +33 -33
- package/templates/services/userService.postgres.js.ejs +30 -30
- package/templates/services/userService.prisma.js.ejs +36 -0
- package/templates/tests/auth.test.js.ejs +83 -66
- package/templates/tests/example.test.js.ejs +109 -112
- package/templates/tests/setup.js.ejs +11 -11
- package/templates/tests/users.test.js.ejs +42 -42
- package/templates/utils/envValidator.js.ejs +23 -0
- package/templates/utils/errors.js.ejs +12 -12
- package/templates/utils/logger.js.ejs +37 -28
- package/templates/utils/response.js.ejs +28 -0
- package/templates/utils/validators.js.ejs +34 -34
- package/templates/config/swagger.json.ejs +0 -194
- package/templates/core/index.js.ejs +0 -24
|
@@ -1,129 +1,152 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
1
|
+
const bcrypt = require('bcryptjs');
|
|
2
|
+
const authService = require('../services/authService');
|
|
3
|
+
const userService = require('../services/userService');
|
|
4
|
+
const { AppError } = require('../utils/errors');
|
|
5
|
+
const { success, created } = require('../utils/response');
|
|
6
|
+
|
|
7
|
+
const register = async (req, res, next) => {
|
|
8
|
+
try {
|
|
9
|
+
const { username, email, password } = req.body;
|
|
10
|
+
|
|
11
|
+
const existingUser = await userService.findByEmail(email);
|
|
12
|
+
if (existingUser) {
|
|
13
|
+
throw new AppError('User already exists with this email', 409);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const hashedPassword = await bcrypt.hash(password, 12);
|
|
17
|
+
const user = await userService.create({ username, email, password: hashedPassword });
|
|
18
|
+
const tokens = authService.generateTokens(user);
|
|
19
|
+
|
|
20
|
+
return created(res, {
|
|
21
|
+
message: 'User registered successfully',
|
|
22
|
+
user: { id: user.id, username: user.username, email: user.email },
|
|
23
|
+
...tokens,
|
|
24
|
+
});
|
|
25
|
+
} catch (error) {
|
|
26
|
+
next(error);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const login = async (req, res, next) => {
|
|
31
|
+
try {
|
|
32
|
+
const { email, password } = req.body;
|
|
33
|
+
|
|
34
|
+
const user = await userService.findByEmail(email);
|
|
35
|
+
if (!user) {
|
|
36
|
+
throw new AppError('Invalid credentials', 401);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const isValidPassword = await bcrypt.compare(password, user.password);
|
|
40
|
+
if (!isValidPassword) {
|
|
41
|
+
throw new AppError('Invalid credentials', 401);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const tokens = authService.generateTokens(user);
|
|
45
|
+
|
|
46
|
+
return success(res, {
|
|
47
|
+
message: 'Login successful',
|
|
48
|
+
user: { id: user.id, username: user.username, email: user.email },
|
|
49
|
+
...tokens,
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
next(error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const refreshToken = async (req, res, next) => {
|
|
57
|
+
try {
|
|
58
|
+
const { refreshToken: token } = req.body;
|
|
59
|
+
|
|
60
|
+
if (!token) {
|
|
61
|
+
throw new AppError('Refresh token is required', 400);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (authService.isTokenBlacklisted(token)) {
|
|
65
|
+
throw new AppError('Token has been revoked', 401);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const decoded = authService.verifyRefreshToken(token);
|
|
69
|
+
const user = await userService.findById(decoded.userId);
|
|
70
|
+
|
|
71
|
+
if (!user) {
|
|
72
|
+
throw new AppError('Invalid refresh token', 401);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Blacklist old refresh token (rotation)
|
|
76
|
+
authService.blacklistToken(token);
|
|
77
|
+
|
|
78
|
+
const tokens = authService.generateTokens(user);
|
|
79
|
+
return success(res, tokens);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
next(error);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const logout = async (req, res, next) => {
|
|
86
|
+
try {
|
|
87
|
+
const authHeader = req.headers['authorization'];
|
|
88
|
+
const accessToken = authHeader && authHeader.split(' ')[1];
|
|
89
|
+
|
|
90
|
+
if (accessToken) {
|
|
91
|
+
authService.blacklistToken(accessToken);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const { refreshToken: token } = req.body;
|
|
95
|
+
if (token) {
|
|
96
|
+
authService.blacklistToken(token);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return success(res, { message: 'Logout successful' });
|
|
100
|
+
} catch (error) {
|
|
101
|
+
next(error);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const forgotPassword = async (req, res, next) => {
|
|
106
|
+
try {
|
|
107
|
+
const { email } = req.body;
|
|
108
|
+
const user = await userService.findByEmail(email);
|
|
109
|
+
|
|
110
|
+
// Always return success to prevent email enumeration
|
|
111
|
+
if (!user) {
|
|
112
|
+
return success(res, { message: 'If an account with that email exists, a reset link has been sent.' });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const resetToken = await authService.generateResetToken(email);
|
|
116
|
+
|
|
117
|
+
// TODO: Send email with reset link
|
|
118
|
+
// await emailService.sendResetEmail(email, resetToken);
|
|
119
|
+
//
|
|
120
|
+
// For development, log the token:
|
|
121
|
+
console.log(`Password reset token for ${email}: ${resetToken}`);
|
|
122
|
+
|
|
123
|
+
return success(res, { message: 'If an account with that email exists, a reset link has been sent.' });
|
|
124
|
+
} catch (error) {
|
|
125
|
+
next(error);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const resetPassword = async (req, res, next) => {
|
|
130
|
+
try {
|
|
131
|
+
const { token, password } = req.body;
|
|
132
|
+
|
|
133
|
+
const email = await authService.consumeResetToken(token);
|
|
134
|
+
if (!email) {
|
|
135
|
+
throw new AppError('Invalid or expired reset token', 400);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const user = await userService.findByEmail(email);
|
|
139
|
+
if (!user) {
|
|
140
|
+
throw new AppError('User not found', 404);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const hashedPassword = await bcrypt.hash(password, 12);
|
|
144
|
+
await userService.updateById(user.id, { password: hashedPassword });
|
|
145
|
+
|
|
146
|
+
return success(res, { message: 'Password has been reset successfully.' });
|
|
147
|
+
} catch (error) {
|
|
148
|
+
next(error);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
module.exports = { register, login, refreshToken, logout, forgotPassword, resetPassword };
|
|
@@ -1,152 +1,92 @@
|
|
|
1
|
-
const exampleService = require('../services/exampleService');
|
|
2
|
-
const { AppError } = require('../utils/errors');
|
|
3
|
-
const {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
next(error);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const { title, description }
|
|
66
|
-
|
|
67
|
-
if (!
|
|
68
|
-
throw new AppError('
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const updateExample = async (req, res, next) => {
|
|
94
|
-
try {
|
|
95
|
-
const { id } = req.params;
|
|
96
|
-
const { title, description } = req.body;
|
|
97
|
-
|
|
98
|
-
logger.info('Updating example', { id });
|
|
99
|
-
|
|
100
|
-
const example = await exampleService.updateExample(id, {
|
|
101
|
-
title,
|
|
102
|
-
description,
|
|
103
|
-
updatedAt: new Date(),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
if (!example) {
|
|
107
|
-
throw new AppError('Example not found', 404);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
res.json({
|
|
111
|
-
success: true,
|
|
112
|
-
message: 'Example updated successfully',
|
|
113
|
-
data: example,
|
|
114
|
-
});
|
|
115
|
-
} catch (error) {
|
|
116
|
-
logger.error('Error updating example', { id: req.params.id, error: error.message });
|
|
117
|
-
next(error);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Delete example
|
|
123
|
-
*/
|
|
124
|
-
const deleteExample = async (req, res, next) => {
|
|
125
|
-
try {
|
|
126
|
-
const { id } = req.params;
|
|
127
|
-
|
|
128
|
-
logger.info('Deleting example', { id });
|
|
129
|
-
|
|
130
|
-
const deleted = await exampleService.deleteExample(id);
|
|
131
|
-
|
|
132
|
-
if (!deleted) {
|
|
133
|
-
throw new AppError('Example not found', 404);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
res.json({
|
|
137
|
-
success: true,
|
|
138
|
-
message: 'Example deleted successfully',
|
|
139
|
-
});
|
|
140
|
-
} catch (error) {
|
|
141
|
-
logger.error('Error deleting example', { id: req.params.id, error: error.message });
|
|
142
|
-
next(error);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
module.exports = {
|
|
147
|
-
getAllExamples,
|
|
148
|
-
getExampleById,
|
|
149
|
-
createExample,
|
|
150
|
-
updateExample,
|
|
151
|
-
deleteExample,
|
|
152
|
-
};
|
|
1
|
+
const exampleService = require('../services/exampleService');
|
|
2
|
+
const { AppError } = require('../utils/errors');
|
|
3
|
+
const { success, created, paginated } = require('../utils/response');
|
|
4
|
+
const { createLogger } = require('../utils/logger');
|
|
5
|
+
|
|
6
|
+
const logger = createLogger('ExampleController');
|
|
7
|
+
|
|
8
|
+
const getAllExamples = async (req, res, next) => {
|
|
9
|
+
try {
|
|
10
|
+
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
|
|
11
|
+
const limit = Math.min(100, Math.max(1, parseInt(req.query.limit, 10) || 10));
|
|
12
|
+
|
|
13
|
+
logger.info('Fetching examples', { page, limit });
|
|
14
|
+
const result = await exampleService.getAllExamples(page, limit);
|
|
15
|
+
|
|
16
|
+
return paginated(res, result.examples, {
|
|
17
|
+
page,
|
|
18
|
+
limit,
|
|
19
|
+
total: result.total,
|
|
20
|
+
totalPages: result.totalPages,
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
logger.error('Error fetching examples', { error: error.message });
|
|
24
|
+
next(error);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const getExampleById = async (req, res, next) => {
|
|
29
|
+
try {
|
|
30
|
+
const { id } = req.params;
|
|
31
|
+
const example = await exampleService.getExampleById(id);
|
|
32
|
+
|
|
33
|
+
if (!example) {
|
|
34
|
+
throw new AppError('Example not found', 404);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return success(res, example);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
next(error);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const createExample = async (req, res, next) => {
|
|
44
|
+
try {
|
|
45
|
+
const { title, description } = req.body;
|
|
46
|
+
|
|
47
|
+
if (!title || !description) {
|
|
48
|
+
throw new AppError('Title and description are required', 400);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
logger.info('Creating example', { title });
|
|
52
|
+
const example = await exampleService.createExample({ title, description });
|
|
53
|
+
|
|
54
|
+
return created(res, example);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
next(error);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const updateExample = async (req, res, next) => {
|
|
61
|
+
try {
|
|
62
|
+
const { id } = req.params;
|
|
63
|
+
const { title, description } = req.body;
|
|
64
|
+
|
|
65
|
+
const example = await exampleService.updateExample(id, { title, description });
|
|
66
|
+
|
|
67
|
+
if (!example) {
|
|
68
|
+
throw new AppError('Example not found', 404);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return success(res, example);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
next(error);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const deleteExample = async (req, res, next) => {
|
|
78
|
+
try {
|
|
79
|
+
const { id } = req.params;
|
|
80
|
+
const deleted = await exampleService.deleteExample(id);
|
|
81
|
+
|
|
82
|
+
if (!deleted) {
|
|
83
|
+
throw new AppError('Example not found', 404);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return success(res, { message: 'Example deleted successfully' });
|
|
87
|
+
} catch (error) {
|
|
88
|
+
next(error);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
module.exports = { getAllExamples, getExampleById, createExample, updateExample, deleteExample };
|
|
@@ -1,60 +1,52 @@
|
|
|
1
|
-
const userService = require('../services/userService');
|
|
2
|
-
const { AppError } = require('../utils/errors');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
module.exports = {
|
|
57
|
-
getProfile,
|
|
58
|
-
updateProfile,
|
|
59
|
-
deleteProfile,
|
|
60
|
-
};
|
|
1
|
+
const userService = require('../services/userService');
|
|
2
|
+
const { AppError } = require('../utils/errors');
|
|
3
|
+
const { success } = require('../utils/response');
|
|
4
|
+
|
|
5
|
+
const getProfile = async (req, res, next) => {
|
|
6
|
+
try {
|
|
7
|
+
const user = await userService.findById(req.user.userId);
|
|
8
|
+
if (!user) {
|
|
9
|
+
throw new AppError('User not found', 404);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return success(res, {
|
|
13
|
+
user: {
|
|
14
|
+
id: user.id,
|
|
15
|
+
username: user.username,
|
|
16
|
+
email: user.email,
|
|
17
|
+
createdAt: user.createdAt,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
next(error);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const updateProfile = async (req, res, next) => {
|
|
26
|
+
try {
|
|
27
|
+
const { username } = req.body;
|
|
28
|
+
const updatedUser = await userService.updateById(req.user.userId, { username });
|
|
29
|
+
|
|
30
|
+
return success(res, {
|
|
31
|
+
message: 'Profile updated successfully',
|
|
32
|
+
user: {
|
|
33
|
+
id: updatedUser.id,
|
|
34
|
+
username: updatedUser.username,
|
|
35
|
+
email: updatedUser.email,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
} catch (error) {
|
|
39
|
+
next(error);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const deleteProfile = async (req, res, next) => {
|
|
44
|
+
try {
|
|
45
|
+
await userService.deleteById(req.user.userId);
|
|
46
|
+
return success(res, { message: 'Profile deleted successfully' });
|
|
47
|
+
} catch (error) {
|
|
48
|
+
next(error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
module.exports = { getProfile, updateProfile, deleteProfile };
|