@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.
Files changed (99) hide show
  1. package/FEAR.js +459 -0
  2. package/FEARServer.js +280 -0
  3. package/controllers/agent.js +438 -0
  4. package/controllers/auth/index.js +345 -0
  5. package/controllers/auth/token.js +50 -0
  6. package/controllers/blog.js +105 -0
  7. package/controllers/brand.js +10 -0
  8. package/controllers/cart.js +425 -0
  9. package/controllers/category.js +9 -0
  10. package/controllers/coupon.js +63 -0
  11. package/controllers/crud/crud.js +508 -0
  12. package/controllers/crud/index.js +36 -0
  13. package/controllers/email.js +34 -0
  14. package/controllers/enquiry.js +65 -0
  15. package/controllers/events.js +9 -0
  16. package/controllers/order.js +125 -0
  17. package/controllers/payment.js +31 -0
  18. package/controllers/product.js +147 -0
  19. package/controllers/review.js +247 -0
  20. package/controllers/tag.js +10 -0
  21. package/controllers/task.js +10 -0
  22. package/controllers/upload.js +41 -0
  23. package/controllers/user.js +401 -0
  24. package/index.js +7 -0
  25. package/libs/agent/index.js +561 -0
  26. package/libs/agent/modules/ai/ai.js +285 -0
  27. package/libs/agent/modules/ai/chat.js +518 -0
  28. package/libs/agent/modules/ai/config.js +688 -0
  29. package/libs/agent/modules/ai/operations.js +787 -0
  30. package/libs/agent/modules/analyze/api.js +546 -0
  31. package/libs/agent/modules/analyze/dorks.js +395 -0
  32. package/libs/agent/modules/ccard/README.md +454 -0
  33. package/libs/agent/modules/ccard/audit.js +479 -0
  34. package/libs/agent/modules/ccard/checker.js +674 -0
  35. package/libs/agent/modules/ccard/payment-processors.json +16 -0
  36. package/libs/agent/modules/ccard/validator.js +629 -0
  37. package/libs/agent/modules/code/analyzer.js +303 -0
  38. package/libs/agent/modules/code/jquery.js +1093 -0
  39. package/libs/agent/modules/code/react.js +1536 -0
  40. package/libs/agent/modules/code/refactor.js +499 -0
  41. package/libs/agent/modules/crypto/exchange.js +564 -0
  42. package/libs/agent/modules/net/proxy.js +409 -0
  43. package/libs/agent/modules/security/cve.js +442 -0
  44. package/libs/agent/modules/security/monitor.js +360 -0
  45. package/libs/agent/modules/security/scanner.js +300 -0
  46. package/libs/agent/modules/security/vulnerability.js +506 -0
  47. package/libs/agent/modules/security/web.js +465 -0
  48. package/libs/agent/modules/utils/browser.js +492 -0
  49. package/libs/agent/modules/utils/colorizer.js +285 -0
  50. package/libs/agent/modules/utils/manager.js +478 -0
  51. package/libs/cloud/index.js +228 -0
  52. package/libs/config/db.js +21 -0
  53. package/libs/config/validator.js +82 -0
  54. package/libs/db/index.js +318 -0
  55. package/libs/emailer/imap.js +126 -0
  56. package/libs/emailer/info.js +41 -0
  57. package/libs/emailer/smtp.js +77 -0
  58. package/libs/handler/async.js +3 -0
  59. package/libs/handler/error.js +66 -0
  60. package/libs/handler/index.js +161 -0
  61. package/libs/logger/index.js +49 -0
  62. package/libs/logger/morgan.js +24 -0
  63. package/libs/passport/passport.js +109 -0
  64. package/libs/search/api.js +384 -0
  65. package/libs/search/features.js +219 -0
  66. package/libs/search/service.js +64 -0
  67. package/libs/swagger/config.js +18 -0
  68. package/libs/swagger/index.js +35 -0
  69. package/libs/validator/index.js +254 -0
  70. package/models/blog.js +31 -0
  71. package/models/brand.js +12 -0
  72. package/models/cart.js +14 -0
  73. package/models/category.js +11 -0
  74. package/models/coupon.js +9 -0
  75. package/models/customer.js +0 -0
  76. package/models/enquiry.js +29 -0
  77. package/models/events.js +13 -0
  78. package/models/order.js +94 -0
  79. package/models/product.js +32 -0
  80. package/models/review.js +14 -0
  81. package/models/tag.js +10 -0
  82. package/models/task.js +11 -0
  83. package/models/user.js +68 -0
  84. package/package.json +12 -0
  85. package/routes/agent.js +615 -0
  86. package/routes/auth.js +13 -0
  87. package/routes/blog.js +19 -0
  88. package/routes/brand.js +15 -0
  89. package/routes/cart.js +105 -0
  90. package/routes/category.js +16 -0
  91. package/routes/coupon.js +15 -0
  92. package/routes/enquiry.js +14 -0
  93. package/routes/events.js +16 -0
  94. package/routes/mail.js +170 -0
  95. package/routes/order.js +19 -0
  96. package/routes/product.js +22 -0
  97. package/routes/review.js +11 -0
  98. package/routes/task.js +12 -0
  99. 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
+ }
@@ -0,0 +1,10 @@
1
+ const Brand = require("../models/brand");
2
+ const methods = require("./crud");
3
+
4
+
5
+ const crud = methods.crudController( Brand );
6
+ for(prop in crud) {
7
+ if(crud.hasOwnProperty(prop)) {
8
+ module.exports[prop] = crud[prop];
9
+ }
10
+ }