@feardread/fear 1.0.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/FEAR.js +459 -0
- package/FEARServer.js +280 -0
- package/controllers/agent.js +438 -0
- package/controllers/auth/index.js +345 -0
- package/controllers/auth/token.js +50 -0
- package/controllers/blog.js +105 -0
- package/controllers/brand.js +10 -0
- package/controllers/cart.js +425 -0
- package/controllers/category.js +9 -0
- package/controllers/coupon.js +63 -0
- package/controllers/crud/crud.js +508 -0
- package/controllers/crud/index.js +36 -0
- package/controllers/email.js +34 -0
- package/controllers/enquiry.js +65 -0
- package/controllers/events.js +9 -0
- package/controllers/order.js +125 -0
- package/controllers/payment.js +31 -0
- package/controllers/product.js +147 -0
- package/controllers/review.js +247 -0
- package/controllers/tag.js +10 -0
- package/controllers/task.js +10 -0
- package/controllers/upload.js +41 -0
- package/controllers/user.js +401 -0
- package/index.js +7 -0
- package/libs/agent/index.js +561 -0
- package/libs/agent/modules/ai/ai.js +285 -0
- package/libs/agent/modules/ai/chat.js +518 -0
- package/libs/agent/modules/ai/config.js +688 -0
- package/libs/agent/modules/ai/operations.js +787 -0
- package/libs/agent/modules/analyze/api.js +546 -0
- package/libs/agent/modules/analyze/dorks.js +395 -0
- package/libs/agent/modules/ccard/README.md +454 -0
- package/libs/agent/modules/ccard/audit.js +479 -0
- package/libs/agent/modules/ccard/checker.js +674 -0
- package/libs/agent/modules/ccard/payment-processors.json +16 -0
- package/libs/agent/modules/ccard/validator.js +629 -0
- package/libs/agent/modules/code/analyzer.js +303 -0
- package/libs/agent/modules/code/jquery.js +1093 -0
- package/libs/agent/modules/code/react.js +1536 -0
- package/libs/agent/modules/code/refactor.js +499 -0
- package/libs/agent/modules/crypto/exchange.js +564 -0
- package/libs/agent/modules/net/proxy.js +409 -0
- package/libs/agent/modules/security/cve.js +442 -0
- package/libs/agent/modules/security/monitor.js +360 -0
- package/libs/agent/modules/security/scanner.js +300 -0
- package/libs/agent/modules/security/vulnerability.js +506 -0
- package/libs/agent/modules/security/web.js +465 -0
- package/libs/agent/modules/utils/browser.js +492 -0
- package/libs/agent/modules/utils/colorizer.js +285 -0
- package/libs/agent/modules/utils/manager.js +478 -0
- package/libs/cloud/index.js +228 -0
- package/libs/config/db.js +21 -0
- package/libs/config/validator.js +82 -0
- package/libs/db/index.js +318 -0
- package/libs/emailer/imap.js +126 -0
- package/libs/emailer/info.js +41 -0
- package/libs/emailer/smtp.js +77 -0
- package/libs/handler/async.js +3 -0
- package/libs/handler/error.js +66 -0
- package/libs/handler/index.js +161 -0
- package/libs/logger/index.js +49 -0
- package/libs/logger/morgan.js +24 -0
- package/libs/passport/passport.js +109 -0
- package/libs/search/api.js +384 -0
- package/libs/search/features.js +219 -0
- package/libs/search/service.js +64 -0
- package/libs/swagger/config.js +18 -0
- package/libs/swagger/index.js +35 -0
- package/libs/validator/index.js +254 -0
- package/models/blog.js +31 -0
- package/models/brand.js +12 -0
- package/models/cart.js +14 -0
- package/models/category.js +11 -0
- package/models/coupon.js +9 -0
- package/models/customer.js +0 -0
- package/models/enquiry.js +29 -0
- package/models/events.js +13 -0
- package/models/order.js +94 -0
- package/models/product.js +32 -0
- package/models/review.js +14 -0
- package/models/tag.js +10 -0
- package/models/task.js +11 -0
- package/models/user.js +68 -0
- package/package.json +12 -0
- package/routes/agent.js +615 -0
- package/routes/auth.js +13 -0
- package/routes/blog.js +19 -0
- package/routes/brand.js +15 -0
- package/routes/cart.js +105 -0
- package/routes/category.js +16 -0
- package/routes/coupon.js +15 -0
- package/routes/enquiry.js +14 -0
- package/routes/events.js +16 -0
- package/routes/mail.js +170 -0
- package/routes/order.js +19 -0
- package/routes/product.js +22 -0
- package/routes/review.js +11 -0
- package/routes/task.js +12 -0
- package/routes/user.js +17 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
const User = require("../../models/user");
|
|
2
|
+
const TokenService = require('./token');
|
|
3
|
+
const handler = require('../../libs/handler');
|
|
4
|
+
const validator = require('../../libs/validator');
|
|
5
|
+
const logger = require('../../libs/logger');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Authentication response helper
|
|
10
|
+
*/
|
|
11
|
+
const response = {
|
|
12
|
+
/**
|
|
13
|
+
* Send successful authentication response
|
|
14
|
+
* @param {object} res - Express response object
|
|
15
|
+
* @param {object} user - User object
|
|
16
|
+
* @param {string} token - JWT token
|
|
17
|
+
* @param {number} statusCode - HTTP status code
|
|
18
|
+
* @param {string} message - Success message
|
|
19
|
+
*/
|
|
20
|
+
success: (res, user, token, statusCode = 200, message = "Authentication successful") => {
|
|
21
|
+
// Remove sensitive data from user object
|
|
22
|
+
const userResponse = {
|
|
23
|
+
_id: user._id,
|
|
24
|
+
email: user.email,
|
|
25
|
+
name: user.name,
|
|
26
|
+
role: user.role,
|
|
27
|
+
createdAt: user.createdAt,
|
|
28
|
+
updatedAt: user.updatedAt
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return res
|
|
32
|
+
.status(statusCode)
|
|
33
|
+
.cookie("jwt", token, TokenService.getCookieOptions())
|
|
34
|
+
.json({
|
|
35
|
+
success: true,
|
|
36
|
+
message,
|
|
37
|
+
data: {
|
|
38
|
+
user: userResponse,
|
|
39
|
+
token
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Send error response
|
|
46
|
+
* @param {object} res - Express response object
|
|
47
|
+
* @param {number} statusCode - HTTP status code
|
|
48
|
+
* @param {string} message - Error message
|
|
49
|
+
* @param {string} error - Detailed error (optional)
|
|
50
|
+
*/
|
|
51
|
+
error: (res, statusCode, message, error = null) => {
|
|
52
|
+
const response = { success: false, message };
|
|
53
|
+
|
|
54
|
+
if (error && process.env.NODE_ENV === "development") response.error = error;
|
|
55
|
+
|
|
56
|
+
return res.status(statusCode).json(response);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* POST /fear/api/auth/login
|
|
63
|
+
* @summary Authenticate user and generate JWT token
|
|
64
|
+
* @description Validates user credentials (email/password) and returns JWT token for authenticated user
|
|
65
|
+
* @tags authentication
|
|
66
|
+
*/
|
|
67
|
+
exports.login = async (req, res) => {
|
|
68
|
+
const { email, password } = req.body;
|
|
69
|
+
|
|
70
|
+
// Validate input
|
|
71
|
+
const validation = validator.input.login({ email, password });
|
|
72
|
+
if (!validation.isValid) {
|
|
73
|
+
return response.sendError(res, 400, validation.message);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log('Authentication attempt for:', email);
|
|
77
|
+
await User.findOne({ email }).select('+password')
|
|
78
|
+
.then((user) => {
|
|
79
|
+
if (!user) return response.error(res, 401, "Invalid credentials");
|
|
80
|
+
|
|
81
|
+
// Verify password
|
|
82
|
+
user.compare(password)
|
|
83
|
+
.then((isPasswordValid) => {
|
|
84
|
+
if (!isPasswordValid) {
|
|
85
|
+
return response.error(res, 401, "Invalid credentials");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const token = TokenService.generateToken(user);
|
|
89
|
+
return response.success(res, user, token, 200, "Login successful");
|
|
90
|
+
})
|
|
91
|
+
.catch(err => response.error(res, 500, 'Server Error'))
|
|
92
|
+
|
|
93
|
+
})
|
|
94
|
+
.catch((error) => {
|
|
95
|
+
logger.error('Login error:', error);
|
|
96
|
+
return response.error(res, 500, "Authentication failed", error.message);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* POST /fear/api/auth/register
|
|
102
|
+
* @summary Register a new user account
|
|
103
|
+
* @description Creates a new user account with provided information and returns JWT token
|
|
104
|
+
* @tags authentication
|
|
105
|
+
*/
|
|
106
|
+
exports.register = async (req, res) => {
|
|
107
|
+
const { email, firstname, lastname, name: providedName, password, ...otherFields } = req.body;
|
|
108
|
+
|
|
109
|
+
// Validate input
|
|
110
|
+
const validation = validator.input.register({
|
|
111
|
+
email, firstname, lastname, name: providedName, password
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!validation.isValid) {
|
|
115
|
+
return response.error(res, 400, validation.message);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
// Check if user already exists
|
|
120
|
+
const existingUser = await User.findOne({ email });
|
|
121
|
+
if (existingUser) {
|
|
122
|
+
return response.error(res, 409, "User with this email already exists");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Create new user
|
|
126
|
+
const userData = {
|
|
127
|
+
...otherFields,
|
|
128
|
+
email: email.toLowerCase(),
|
|
129
|
+
name: validation.name,
|
|
130
|
+
password,
|
|
131
|
+
role: otherFields.role || 'user' // Default role
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const user = await User.create(userData);
|
|
135
|
+
|
|
136
|
+
// Generate token and send response
|
|
137
|
+
const token = TokenService.generateToken(user);
|
|
138
|
+
return response.success(res, user, token, 201, "Registration successful");
|
|
139
|
+
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error('Registration error:', error);
|
|
142
|
+
|
|
143
|
+
// Handle duplicate key error (in case of race condition)
|
|
144
|
+
if (error.code === 11000) {
|
|
145
|
+
return response.error(res, 409, "User with this email already exists");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return response.error(res, 500, "Registration failed", error.message);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* POST /fear/api/auth/logout
|
|
154
|
+
* @summary Log out user and clear JWT cookie
|
|
155
|
+
* @description Clears the JWT token cookie to log out the authenticated user
|
|
156
|
+
* @tags authentication
|
|
157
|
+
*/
|
|
158
|
+
exports.logout = async (req, res) => {
|
|
159
|
+
return res
|
|
160
|
+
.status(200)
|
|
161
|
+
.clearCookie('jwt', {
|
|
162
|
+
httpOnly: true,
|
|
163
|
+
secure: process.env.NODE_ENV === "production",
|
|
164
|
+
sameSite: "strict"
|
|
165
|
+
})
|
|
166
|
+
.json({
|
|
167
|
+
success: true,
|
|
168
|
+
message: "Logout successful"
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* GET /fear/api/auth/me
|
|
174
|
+
* @summary Get current authenticated user profile
|
|
175
|
+
* @description Returns the current user's profile information
|
|
176
|
+
* @tags authentication
|
|
177
|
+
*/
|
|
178
|
+
exports.getCurrentUser = async (req, res) => {
|
|
179
|
+
// req.user is set by isAuthorized middleware
|
|
180
|
+
const user = req.user;
|
|
181
|
+
|
|
182
|
+
const userResponse = {
|
|
183
|
+
_id: user._id,
|
|
184
|
+
email: user.email,
|
|
185
|
+
name: user.name,
|
|
186
|
+
role: user.role,
|
|
187
|
+
createdAt: user.createdAt,
|
|
188
|
+
updatedAt: user.updatedAt
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
return res.status(200).json({
|
|
192
|
+
success: true,
|
|
193
|
+
data: { user: userResponse }
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* PUT /fear/api/auth/refresh-token
|
|
199
|
+
* @summary Refresh JWT token
|
|
200
|
+
* @description Generates a new JWT token for authenticated user
|
|
201
|
+
* @tags authentication
|
|
202
|
+
*/
|
|
203
|
+
exports.refreshToken = async (req, res) => {
|
|
204
|
+
const user = req.user; // Set by isAuthorized middleware
|
|
205
|
+
|
|
206
|
+
const newToken = TokenService.generateToken(user);
|
|
207
|
+
return response.success(res, user, newToken, 200, "Token refreshed successfully");
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Middleware: Verify JWT token and authenticate user
|
|
212
|
+
* @summary Checks if user has valid JWT token in cookies or Authorization header
|
|
213
|
+
* @description Validates JWT token and attaches user object to request
|
|
214
|
+
* @tags middleware, authentication
|
|
215
|
+
*/
|
|
216
|
+
exports.isAuthorized = async (req, res, next) => {
|
|
217
|
+
let token;
|
|
218
|
+
|
|
219
|
+
// Check for token in cookies first, then Authorization header
|
|
220
|
+
if (req.cookies?.jwt) {
|
|
221
|
+
token = req.cookies.jwt;
|
|
222
|
+
} else if (req.headers.authorization?.startsWith('Bearer ')) {
|
|
223
|
+
token = req.headers.authorization.split(' ')[1];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (!token) {
|
|
227
|
+
return response.error(res, 401, "Access denied. Authentication required.");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
// Verify token
|
|
232
|
+
const decodedToken = TokenService.verifyToken(token);
|
|
233
|
+
|
|
234
|
+
// Get user from database
|
|
235
|
+
const user = await User.findById(decodedToken.id);
|
|
236
|
+
if (!user) {
|
|
237
|
+
return response.error(res, 401, "Invalid token. User not found.");
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Check if user is still active (optional)
|
|
241
|
+
if (user.isActive === false) {
|
|
242
|
+
return response.error(res, 401, "Account has been deactivated.");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Attach user to request
|
|
246
|
+
req.user = user;
|
|
247
|
+
req.token = token;
|
|
248
|
+
next();
|
|
249
|
+
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error('Authorization error:', error);
|
|
252
|
+
|
|
253
|
+
if (error.name === 'JsonWebTokenError') {
|
|
254
|
+
return response.error(res, 401, "Invalid token.");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (error.name === 'TokenExpiredError') {
|
|
258
|
+
return response.error(res, 401, "Token has expired. Please login again.");
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return response.error(res, 500, "Authentication failed", error.message);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Middleware: Check if user has admin role
|
|
267
|
+
* @summary Verifies that authenticated user has admin privileges
|
|
268
|
+
* @description Checks if req.user.role equals 'admin'. Must be used after isAuthorized middleware
|
|
269
|
+
* @tags middleware, authorization
|
|
270
|
+
*/
|
|
271
|
+
exports.isAdmin = async (req, res, next) => {
|
|
272
|
+
if (!req.user) {
|
|
273
|
+
return response.error(res, 401, "Authentication required");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (req.user.role !== "admin") {
|
|
277
|
+
return response.error(res, 403, "Access denied. Admin privileges required.");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
next();
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Middleware factory: Check if user has required role(s)
|
|
285
|
+
* @summary Creates middleware to verify user has one of the specified roles
|
|
286
|
+
* @description Returns middleware function that checks if authenticated user's role is in allowed roles list
|
|
287
|
+
* @tags middleware, authorization
|
|
288
|
+
* @param {...string} roles - Allowed roles (e.g., 'admin', 'moderator', 'user')
|
|
289
|
+
* @returns {function} Express middleware function
|
|
290
|
+
*/
|
|
291
|
+
exports.authorizeRoles = (...roles) => {
|
|
292
|
+
return handler.async(async (req, res, next) => {
|
|
293
|
+
if (!req.user) {
|
|
294
|
+
return response.error(res, 401, "Authentication required");
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (!roles.includes(req.user.role)) {
|
|
298
|
+
return response.error(
|
|
299
|
+
res,
|
|
300
|
+
403,
|
|
301
|
+
`Access denied. Required roles: ${roles.join(', ')}. Your role: ${req.user.role}`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
next();
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Middleware: Optional authentication
|
|
311
|
+
* @summary Attempts to authenticate user but doesn't fail if no token provided
|
|
312
|
+
* @description Useful for routes that behave differently for authenticated vs anonymous users
|
|
313
|
+
* @tags middleware, authentication
|
|
314
|
+
*/
|
|
315
|
+
exports.optionalAuth = async (req, res, next) => {
|
|
316
|
+
let token;
|
|
317
|
+
|
|
318
|
+
if (req.cookies?.jwt) {
|
|
319
|
+
token = req.cookies.jwt;
|
|
320
|
+
} else if (req.headers.authorization?.startsWith('Bearer ')) {
|
|
321
|
+
token = req.headers.authorization.split(' ')[1];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (!token) {
|
|
325
|
+
return next();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
const decodedToken = TokenService.verifyToken(token);
|
|
330
|
+
const user = await User.findById(decodedToken.id);
|
|
331
|
+
|
|
332
|
+
if (user && user.isActive !== false) {
|
|
333
|
+
req.user = user;
|
|
334
|
+
req.token = token;
|
|
335
|
+
}
|
|
336
|
+
} catch (error) {
|
|
337
|
+
// Silently fail for optional auth
|
|
338
|
+
console.log('Optional auth failed:', error.message);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
next();
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// Export TokenService and other utilities for use in other modules
|
|
345
|
+
exports.AuthResponse = response;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const jwt = require("jsonwebtoken");
|
|
2
|
+
// Configuration constants
|
|
3
|
+
const JWT_EXPIRES_IN = 24 * 60 * 60; // 24 hours in seconds
|
|
4
|
+
const COOKIE_MAX_AGE = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* JWT Token utilities
|
|
8
|
+
*/
|
|
9
|
+
module.exports = class TokenService {
|
|
10
|
+
/**
|
|
11
|
+
* Generate JWT token for user
|
|
12
|
+
* @param {object} user - User object
|
|
13
|
+
* @returns {string} JWT token
|
|
14
|
+
*/
|
|
15
|
+
static generateToken(user) {
|
|
16
|
+
return jwt.sign(
|
|
17
|
+
{
|
|
18
|
+
id: user._id,
|
|
19
|
+
email: user.email,
|
|
20
|
+
role: user.role || 'user'
|
|
21
|
+
},
|
|
22
|
+
process.env.JWT_SECRET,
|
|
23
|
+
{
|
|
24
|
+
expiresIn: JWT_EXPIRES_IN
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Verify JWT token
|
|
31
|
+
* @param {string} token - JWT token to verify
|
|
32
|
+
* @returns {object} Decoded token payload
|
|
33
|
+
*/
|
|
34
|
+
static verifyToken(token) {
|
|
35
|
+
return jwt.verify(token, process.env.JWT_SECRET);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get cookie options based on environment
|
|
40
|
+
* @returns {object} Cookie configuration
|
|
41
|
+
*/
|
|
42
|
+
static getCookieOptions() {
|
|
43
|
+
return {
|
|
44
|
+
httpOnly: true,
|
|
45
|
+
secure: process.env.NODE_ENV === "production",
|
|
46
|
+
sameSite: "strict",
|
|
47
|
+
maxAge: COOKIE_MAX_AGE,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const Blog = require("../models/blog");
|
|
2
|
+
const User = require("../models/user");
|
|
3
|
+
|
|
4
|
+
const methods = require("./crud");
|
|
5
|
+
|
|
6
|
+
exports.likes = async (req, res) => {
|
|
7
|
+
const { blogId } = req.body;
|
|
8
|
+
//validateMongoDbId(blogId);
|
|
9
|
+
|
|
10
|
+
const blog = await Blog.findById(blogId);
|
|
11
|
+
const loginUserId = req.user._id;
|
|
12
|
+
const isLiked = blog.isLiked;
|
|
13
|
+
const alreadyDisliked = blog?.dislikes?.find(
|
|
14
|
+
(userId) => userId.toString() === loginUserId.toString()
|
|
15
|
+
);
|
|
16
|
+
if (alreadyDisliked) {
|
|
17
|
+
await Blog.findByIdAndUpdate( blogId, {
|
|
18
|
+
$pull: { dislikes: loginUserId },
|
|
19
|
+
isDisliked: false,
|
|
20
|
+
},
|
|
21
|
+
{ new: true }
|
|
22
|
+
);
|
|
23
|
+
res.json(blog);
|
|
24
|
+
}
|
|
25
|
+
if (isLiked) {
|
|
26
|
+
|
|
27
|
+
await Blog.findByIdAndUpdate( blogId, {
|
|
28
|
+
$pull: { likes: loginUserId },
|
|
29
|
+
isLiked: false },
|
|
30
|
+
{ new: true })
|
|
31
|
+
.then((blog) => {
|
|
32
|
+
res.status(200).json({success: true, result: blog});
|
|
33
|
+
})
|
|
34
|
+
.catch((error) => {
|
|
35
|
+
res.status(400).json({success: false, error});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
} else {
|
|
39
|
+
const blog = await Blog.findByIdAndUpdate(
|
|
40
|
+
blogId,
|
|
41
|
+
{
|
|
42
|
+
$push: { likes: loginUserId },
|
|
43
|
+
isLiked: true,
|
|
44
|
+
},
|
|
45
|
+
{ new: true }
|
|
46
|
+
);
|
|
47
|
+
res.json(blog);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
exports.dislikes = async (req, res) => {
|
|
52
|
+
const { blogId } = req.body;
|
|
53
|
+
validateMongoDbId(blogId);
|
|
54
|
+
|
|
55
|
+
const blog = await Blog.findById(blogId);
|
|
56
|
+
const loginUserId = req.user._id;
|
|
57
|
+
const isDisLiked = blog.isDisliked;
|
|
58
|
+
const alreadyLiked = blog.likes.find(
|
|
59
|
+
(userId) => userId?.toString() === loginUserId?.toString()
|
|
60
|
+
);
|
|
61
|
+
if (alreadyLiked) {
|
|
62
|
+
const blog = await Blog.findByIdAndUpdate(
|
|
63
|
+
blogId,
|
|
64
|
+
{
|
|
65
|
+
$pull: { likes: loginUserId },
|
|
66
|
+
isLiked: false,
|
|
67
|
+
},
|
|
68
|
+
{ new: true }
|
|
69
|
+
);
|
|
70
|
+
res.json(blog);
|
|
71
|
+
}
|
|
72
|
+
if (isDisLiked) {
|
|
73
|
+
const blog = await Blog.findByIdAndUpdate(
|
|
74
|
+
blogId,
|
|
75
|
+
{
|
|
76
|
+
$pull: { dislikes: loginUserId },
|
|
77
|
+
isDisliked: false,
|
|
78
|
+
},
|
|
79
|
+
{ new: true }
|
|
80
|
+
);
|
|
81
|
+
res.json(blog);
|
|
82
|
+
} else {
|
|
83
|
+
const blog = await Blog.findByIdAndUpdate(
|
|
84
|
+
blogId,
|
|
85
|
+
{
|
|
86
|
+
$push: { dislikes: loginUserId },
|
|
87
|
+
isDisliked: true,
|
|
88
|
+
},
|
|
89
|
+
{ new: true }
|
|
90
|
+
);
|
|
91
|
+
res.json(blog);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
exports.sections = async (req, res) => {
|
|
96
|
+
const categories = ['Marketing', 'Nextjs', 'React', 'Nodejs', 'Tailwindcss'];
|
|
97
|
+
return res.json({ sections: categories, success:true });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const crud = methods.crudController( Blog );
|
|
101
|
+
for(prop in crud) {
|
|
102
|
+
if(crud.hasOwnProperty(prop)) {
|
|
103
|
+
module.exports[prop] = crud[prop];
|
|
104
|
+
}
|
|
105
|
+
}
|