@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,21 @@
1
+ const mongoose = require("mongoose");
2
+
3
+ const connectDB = async () => {
4
+ try {
5
+ const uri = process.env.MONGO_URI || "mongodb://localhost/bags-ecommerce";
6
+ await mongoose
7
+ .connect(uri, {
8
+ useNewUrlParser: true,
9
+ useCreateIndex: true,
10
+ useUnifiedTopology: true,
11
+ })
12
+ .catch((error) => console.log(error));
13
+ const connection = mongoose.connection;
14
+ console.log("MONGODB CONNECTED SUCCESSFULLY!");
15
+ } catch (error) {
16
+ console.log(error);
17
+ return error;
18
+ }
19
+ };
20
+
21
+ module.exports = connectDB;
@@ -0,0 +1,82 @@
1
+ const { check, validationResult } = require("express-validator");
2
+
3
+ const userSignUpValidationRules = () => {
4
+ return [
5
+ check("name", "Name is required").not().isEmpty(),
6
+ check("email", "Invalid email").not().isEmpty().isEmail(),
7
+ check("password", "Please enter a password with 4 or more characters")
8
+ .not()
9
+ .isEmpty()
10
+ .isLength({ min: 4 }),
11
+ ];
12
+ };
13
+
14
+ const userSignInValidationRules = () => {
15
+ return [
16
+ check("email", "Invalid email").not().isEmpty().isEmail(),
17
+ check("password", "Invalid password").not().isEmpty().isLength({ min: 4 }),
18
+ ];
19
+ };
20
+
21
+ const userContactUsValidationRules = () => {
22
+ return [
23
+ check("name", "Please enter a name").not().isEmpty(),
24
+ check("email", "Please enter a valid email address")
25
+ .not()
26
+ .isEmpty()
27
+ .isEmail(),
28
+ check("message", "Please enter a message with at least 10 words")
29
+ .not()
30
+ .isEmpty()
31
+ .isLength({ min: 10 }),
32
+ ];
33
+ };
34
+
35
+ const validateSignup = (req, res, next) => {
36
+ const errors = validationResult(req);
37
+ if (!errors.isEmpty()) {
38
+ var messages = [];
39
+ errors.array().forEach((error) => {
40
+ messages.push(error.msg);
41
+ });
42
+ req.flash("error", messages);
43
+ return res.redirect("/user/signup");
44
+ }
45
+ next();
46
+ };
47
+
48
+ const validateSignin = (req, res, next) => {
49
+ const errors = validationResult(req);
50
+ if (!errors.isEmpty()) {
51
+ var messages = [];
52
+ errors.array().forEach((error) => {
53
+ messages.push(error.msg);
54
+ });
55
+ req.flash("error", messages);
56
+ return res.redirect("/user/signin");
57
+ }
58
+ next();
59
+ };
60
+
61
+ const validateContactUs = (req, res, next) => {
62
+ const errors = validationResult(req);
63
+ if (!errors.isEmpty()) {
64
+ var messages = [];
65
+ errors.array().forEach((error) => {
66
+ messages.push(error.msg);
67
+ });
68
+ console.log(messages);
69
+ req.flash("error", messages);
70
+ return res.redirect("/pages/contact-us");
71
+ }
72
+ next();
73
+ };
74
+
75
+ module.exports = {
76
+ userSignUpValidationRules,
77
+ userSignInValidationRules,
78
+ userContactUsValidationRules,
79
+ validateSignup,
80
+ validateSignin,
81
+ validateContactUs,
82
+ };
@@ -0,0 +1,318 @@
1
+ const mongoose = require("mongoose");
2
+
3
+ /**
4
+ * MongoDB connection utility module
5
+ * Provides connection management and ObjectId utilities
6
+ */
7
+ class DatabaseManager {
8
+ constructor() {
9
+ this.isConnected = false;
10
+ this.currentDbName = null;
11
+ this._setupEventListeners();
12
+ }
13
+
14
+ /**
15
+ * Setup mongoose connection event listeners
16
+ * @private
17
+ */
18
+ _setupEventListeners() {
19
+ mongoose.connection.on('connected', () => {
20
+ this.isConnected = true;
21
+ console.log(`✅ MongoDB connected successfully to: ${this.currentDbName}`);
22
+ });
23
+
24
+ mongoose.connection.on('error', (err) => {
25
+ this.isConnected = false;
26
+ console.error('❌ MongoDB connection error:', err);
27
+ });
28
+
29
+ mongoose.connection.on('disconnected', () => {
30
+ this.isConnected = false;
31
+ console.log(`🔌 MongoDB disconnected from: ${this.currentDbName || 'database'}`);
32
+ });
33
+
34
+ mongoose.connection.on('reconnected', () => {
35
+ this.isConnected = true;
36
+ console.log(`🔄 MongoDB reconnected to: ${this.currentDbName}`);
37
+ });
38
+
39
+ // Graceful shutdown handling
40
+ process.on('SIGINT', async () => {
41
+ await this.close();
42
+ process.exit(0);
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Connect to MongoDB database
48
+ * @param {Object} env - Environment configuration object
49
+ * @param {string} env.DB_LINK - MongoDB connection string
50
+ * @param {string} env.DB_NAME - Database name
51
+ * @param {Function} [callback] - Optional callback function
52
+ * @param {Object} [options] - Additional mongoose connection options
53
+ * @returns {Promise<void>}
54
+ */
55
+ async connect(env, callback = null, options = {}) {
56
+ try {
57
+ // Validate required environment variables
58
+ if (!env.DB_LINK) {
59
+ throw new Error('DB_LINK is required in environment configuration');
60
+ }
61
+ if (!env.DB_NAME) {
62
+ throw new Error('DB_NAME is required in environment configuration');
63
+ }
64
+
65
+ // Check if already connected to the same database
66
+ if (this.isConnected && this.currentDbName === env.DB_NAME) {
67
+ console.log(`📋 Already connected to MongoDB: ${env.DB_NAME}`);
68
+ if (callback) callback();
69
+ return;
70
+ }
71
+
72
+ // Close existing connection if connected to different database
73
+ if (this.isConnected && this.currentDbName !== env.DB_NAME) {
74
+ await this.close();
75
+ }
76
+
77
+ // Set mongoose configuration
78
+ mongoose.set("strictQuery", false);
79
+
80
+ // Default connection options
81
+ const defaultOptions = {
82
+ dbName: env.DB_NAME,
83
+ maxPoolSize: 10,
84
+ serverSelectionTimeoutMS: 5000,
85
+ socketTimeoutMS: 45000,
86
+ bufferCommands: false,
87
+ ...options
88
+ };
89
+
90
+ this.currentDbName = env.DB_NAME;
91
+
92
+ // Connect to MongoDB
93
+ await mongoose.connect(env.DB_LINK, defaultOptions);
94
+
95
+ // Execute callback if provided
96
+ if (callback) callback();
97
+
98
+ } catch (error) {
99
+ this.isConnected = false;
100
+ console.error('❌ Failed to connect to MongoDB:', error.message);
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Disconnect from MongoDB
107
+ * @param {Function} [callback] - Optional callback function
108
+ * @returns {Promise<void>}
109
+ */
110
+ async close(callback = null) {
111
+ try {
112
+ if (!this.isConnected) {
113
+ console.log('📋 MongoDB is not connected');
114
+ if (callback) callback();
115
+ return;
116
+ }
117
+
118
+ await mongoose.disconnect();
119
+ this.isConnected = false;
120
+
121
+ if (callback) callback();
122
+
123
+ } catch (error) {
124
+ console.error('❌ Error disconnecting from MongoDB:', error.message);
125
+ throw error;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Get connection status
131
+ * @returns {Object} Connection status information
132
+ */
133
+ getConnectionStatus() {
134
+ return {
135
+ isConnected: this.isConnected,
136
+ readyState: mongoose.connection.readyState,
137
+ dbName: this.currentDbName,
138
+ host: mongoose.connection.host,
139
+ port: mongoose.connection.port
140
+ };
141
+ }
142
+
143
+ /**
144
+ * Wait for database connection to be ready
145
+ * @param {number} [timeout=10000] - Timeout in milliseconds
146
+ * @returns {Promise<void>}
147
+ */
148
+ async waitForConnection(timeout = 10000) {
149
+ return new Promise((resolve, reject) => {
150
+ if (this.isConnected) {
151
+ resolve();
152
+ return;
153
+ }
154
+
155
+ const timeoutId = setTimeout(() => {
156
+ reject(new Error(`Connection timeout after ${timeout}ms`));
157
+ }, timeout);
158
+
159
+ mongoose.connection.once('connected', () => {
160
+ clearTimeout(timeoutId);
161
+ resolve();
162
+ });
163
+
164
+ mongoose.connection.once('error', (error) => {
165
+ clearTimeout(timeoutId);
166
+ reject(error);
167
+ });
168
+ });
169
+ }
170
+ }
171
+
172
+ // Create singleton instance
173
+ const dbManager = new DatabaseManager();
174
+
175
+ /**
176
+ * ObjectId utility functions
177
+ */
178
+ const ObjectIdUtils = {
179
+ /**
180
+ * Create new ObjectId from string or return existing ObjectId
181
+ * @param {string|mongoose.Types.ObjectId} id - ID to wrap
182
+ * @returns {mongoose.Types.ObjectId} ObjectId instance
183
+ */
184
+ wrapId(id) {
185
+ if (!id) {
186
+ throw new Error('ID parameter is required');
187
+ }
188
+
189
+ if (mongoose.Types.ObjectId.isValid(id)) {
190
+ return new mongoose.Types.ObjectId(id);
191
+ }
192
+
193
+ throw new Error(`Invalid ObjectId format: ${id}`);
194
+ },
195
+
196
+ /**
197
+ * Validate if string is a valid ObjectId
198
+ * @param {string} id - ID to validate
199
+ * @param {boolean} [throwError=true] - Whether to throw error on invalid ID
200
+ * @returns {boolean} True if valid ObjectId
201
+ */
202
+ validate(id, throwError = true) {
203
+ if (!id) {
204
+ if (throwError) {
205
+ throw new Error('ID parameter is required');
206
+ }
207
+ return false;
208
+ }
209
+
210
+ const isValid = mongoose.Types.ObjectId.isValid(id);
211
+
212
+ if (!isValid && throwError) {
213
+ throw new Error(`Invalid ObjectId format: ${id}`);
214
+ }
215
+
216
+ return isValid;
217
+ },
218
+
219
+ /**
220
+ * Generate new ObjectId
221
+ * @returns {mongoose.Types.ObjectId} New ObjectId
222
+ */
223
+ generate() {
224
+ return new mongoose.Types.ObjectId();
225
+ },
226
+
227
+ /**
228
+ * Convert ObjectId to string
229
+ * @param {mongoose.Types.ObjectId} objectId - ObjectId to convert
230
+ * @returns {string} String representation of ObjectId
231
+ */
232
+ toString(objectId) {
233
+ if (!objectId) {
234
+ throw new Error('ObjectId parameter is required');
235
+ }
236
+ return objectId.toString();
237
+ },
238
+
239
+ /**
240
+ * Check if two ObjectIds are equal
241
+ * @param {string|mongoose.Types.ObjectId} id1 - First ID
242
+ * @param {string|mongoose.Types.ObjectId} id2 - Second ID
243
+ * @returns {boolean} True if IDs are equal
244
+ */
245
+ areEqual(id1, id2) {
246
+ if (!id1 || !id2) return false;
247
+
248
+ try {
249
+ const objId1 = this.wrapId(id1);
250
+ const objId2 = this.wrapId(id2);
251
+ return objId1.equals(objId2);
252
+ } catch (error) {
253
+ return false;
254
+ }
255
+ }
256
+ };
257
+
258
+ /**
259
+ * Legacy compatibility functions (backwards compatibility)
260
+ */
261
+ const legacyAPI = {
262
+ /**
263
+ * Legacy run function for backwards compatibility
264
+ * @deprecated Use dbManager.connect() instead
265
+ */
266
+ async run(env, callback) {
267
+ console.warn('⚠️ Warning: run() is deprecated. Use connect() instead.');
268
+ return await dbManager.connect(env, callback);
269
+ },
270
+
271
+ /**
272
+ * Legacy close function for backwards compatibility
273
+ * @deprecated Use dbManager.close() instead
274
+ */
275
+ async close(callback) {
276
+ console.warn('⚠️ Warning: close() is deprecated. Use disconnect() instead.');
277
+ return await dbManager.disconnect(callback);
278
+ },
279
+
280
+ /**
281
+ * Legacy store function (placeholder)
282
+ * @deprecated This function was not implemented in original code
283
+ */
284
+ store() {
285
+ console.warn('⚠️ Warning: store() function is not implemented');
286
+ return null;
287
+ },
288
+
289
+ /**
290
+ * Legacy wrapId function for backwards compatibility
291
+ * @deprecated Use ObjectIdUtils.wrapId() instead
292
+ */
293
+ wrapId(id) {
294
+ console.warn('⚠️ Warning: wrapId() is deprecated. Use ObjectIdUtils.wrapId() instead.');
295
+ return ObjectIdUtils.wrapId(id);
296
+ },
297
+
298
+ /**
299
+ * Legacy validate function for backwards compatibility
300
+ * @deprecated Use ObjectIdUtils.validate() instead
301
+ */
302
+ validate(id) {
303
+ console.warn('⚠️ Warning: validate() is deprecated. Use ObjectIdUtils.validate() instead.');
304
+ return ObjectIdUtils.validate(id);
305
+ }
306
+ };
307
+
308
+ module.exports = {
309
+ // New recommended API
310
+ connect: (env, callback, options) => dbManager.connect(env, callback, options),
311
+ disconnect: (callback) => dbManager.close(callback),
312
+ getConnectionStatus: () => dbManager.getConnectionStatus(),
313
+ waitForConnection: (timeout) => dbManager.waitForConnection(timeout),
314
+ ObjectId: ObjectIdUtils,
315
+ dbManager,
316
+ mongoose,
317
+ ...legacyAPI
318
+ };
@@ -0,0 +1,126 @@
1
+ const ImapClient = require("emailjs-imap-client");
2
+ const { ParsedMail, simpleParser } = require("mailparser");
3
+
4
+
5
+ module.exports = class Worker {
6
+ constructor (mailinfo) {
7
+ this.mailinfo = mailinfo;
8
+ }
9
+
10
+ connectToServer = async (req, res) => {
11
+ const client = new ImapClient.default(
12
+ this.mailinfo.imap.host,
13
+ this.mailinfo.imap.port,
14
+ { auth: this.mailinfo.imap.auth }
15
+ );
16
+
17
+ client.logLevel = client.LOG_LEVEL_NONE; // keep the output logging
18
+ client.onerror = (error) => {
19
+ console.log("IMAP.Worker.listMailboxes(): Connection error", error);
20
+ };
21
+
22
+ await client.connect();
23
+
24
+ return client;
25
+ }
26
+
27
+ listMailboxes = async (req, res) => {
28
+ const client = await this.connectToServer();
29
+ const mailboxes = await client.listMailboxes();
30
+ await client.close();
31
+
32
+ const iterateChildren = (inArray) => {
33
+
34
+ inArray.forEach((inValue: any) => {
35
+ finalMailboxes.push({
36
+ name: inValue.name,
37
+ path: inValue.path
38
+ });
39
+ iterateChildren(inValue.children);
40
+ });
41
+ };
42
+ iterateChildren(mailboxes.children);
43
+
44
+ return finalMailboxes;
45
+ }
46
+
47
+ listMessages = async (options) => {
48
+ const client = await this.connectToServer();
49
+ const mailbox = await client.selectMailbox(options.mailbox);
50
+
51
+ if (mailbox.exists === 0) {
52
+ await client.close();
53
+ return [];
54
+ }
55
+
56
+ const messages = await client.listMessages(
57
+ options.mailbox, "1:*", ["uid", "envelope"]
58
+ );
59
+
60
+ await client.close();
61
+ const finalMessages = [];
62
+ messages.forEach((value) => {
63
+ finalMessages.push({
64
+ id: value.uid,
65
+ date: value.envelope.date,
66
+ from: value.envelope.from[0].address,
67
+ subject: value.envelope.subject
68
+ });
69
+ });
70
+
71
+ return finalMessages;
72
+ }
73
+
74
+
75
+ /**
76
+ * Gets the plain text body of a single message.
77
+ *
78
+ * @param options An object implementing the ICallOptions interface.
79
+ * @return The plain text body of the message.
80
+ */
81
+ getMessageBody = async (options) => {
82
+ const client = await this.connectToServer();
83
+ const messages = await client.listMessages(
84
+ options.mailbox,
85
+ options.id,
86
+ { byUid: true }
87
+ );
88
+ const parsed = await simpleParser(messages[0]["body[]"]);
89
+ await client.close();
90
+
91
+ return parsed?.text;
92
+ }
93
+
94
+
95
+ /**
96
+ * Deletes a single message.
97
+ *
98
+ * @param options An object implementing the ICallOptions interface.
99
+ */
100
+ deleteMessage = async (options) => {
101
+ const client = await this.connectToServer();
102
+ const messages = await client.listMessages(
103
+ options.mailbox,
104
+ options.id, // specifying a specific message ID
105
+ ["uid"], // body can be in multiple parts, it’s actually an array
106
+ { byUid: true } // listing messages based on a specific ID
107
+ );
108
+ if (options.mailbox !== 'Deleted'){
109
+ await client.copyMessages(
110
+ options.mailbox,
111
+ messages[0]['uid'],
112
+ 'Deleted',
113
+ { byUid: true } // tell the method that we are passing a unique ID
114
+ );
115
+ }
116
+ await client.deleteMessages(
117
+ options.mailbox,
118
+ messages[0]['uid'],
119
+ // inCallOptions.id,
120
+ { byUid: true } // tell the method that we are passing a unique ID
121
+ );
122
+ await client.close(); // no return
123
+ }
124
+
125
+
126
+ }
@@ -0,0 +1,41 @@
1
+ require("dotenv").config({ path: "backend/.env" });
2
+
3
+ module.exports = {
4
+ "smtp": {
5
+ "service": process.env.SMTP_SERVICE,
6
+ "host": process.env.SMTP_HOST,
7
+ "port": process.env.SMTP_PORT,
8
+ "auth": {
9
+ "user": process.env.SMTP_MAIL,
10
+ "pass": process.env.SMTP_PASS
11
+ },
12
+ "apps": {
13
+ "gfolio": {
14
+ "auth": {
15
+ "user": process.env.SMTP_MAIL,
16
+ "pass": process.env.SMTP_PASS
17
+ },
18
+ },
19
+ "gdrea": {
20
+ "auth": {
21
+ "user": process.env.SMTP_MAIL,
22
+ "pass": process.env.SMTP_PASS
23
+ },
24
+ },
25
+ "jbird": {
26
+ "auth": {
27
+ "user": process.env.SMTP_MAIL,
28
+ "pass": process.env.SMTP_PASS
29
+ },
30
+ },
31
+ }
32
+ },
33
+ "imap": {
34
+ "host": "mail.mydomain.com",
35
+ "port": 999,
36
+ "auth": {
37
+ "user": "user@domain.com",
38
+ "pass": "xxx"
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,77 @@
1
+ const nodemailer = require("nodemailer");
2
+
3
+ module.exports = class Worker {
4
+ constructor(mailinfo) {
5
+ this.mailinfo = mailinfo;
6
+ this.email = mailinfo.smtp.auth.user;
7
+ }
8
+
9
+ /**
10
+ * Send a message.
11
+ *
12
+ * @param options An object containing to, from, subject and text properties (matches the IContact interface,
13
+ * but can't be used since the type comes from nodemailer, not app code).
14
+ * @return A Promise that eventually resolves to a string (null for success, error message for an error).
15
+ */
16
+ sendMessage = async (options) => {
17
+ return new Promise((res, req) => {
18
+ const transport = nodemailer.createTransport(this.mailinfo.smtp);
19
+
20
+ transport.sendMail( options, (error, info) => {
21
+ if (error) return reject(error);
22
+ return resolve();
23
+ });
24
+ });
25
+ }
26
+
27
+ sendProjectEmail = async (data) => {
28
+ return new Promise((resolve, reject) => {
29
+ let transporter = nodemailer.createTransport(this.mailinfo.smtp);
30
+
31
+ const { $subject, fullname, company, email, phone, budget, about } = data;
32
+
33
+ const message = `Fullname: ${fullname}\n`
34
+ + `Email: ${email}\n`
35
+ + `Budget: ${budget}\n`
36
+ + `Phone number: + ${phone}\n`
37
+ + `Company: ${company}\n`
38
+ + `About project: ${about}\n`
39
+
40
+ const options = {
41
+ from: email,
42
+ to: this.email,
43
+ subject: $subject || `Gfolio Contact Form Submission`,
44
+ text: message,
45
+ };
46
+
47
+ transporter.sendMail(options, function(error, info) {
48
+ if (error) {
49
+ return reject({ message: `An error has occured: ${error}`});
50
+ }
51
+ return resolve({ message: 'Email sent succesfully!'})
52
+ })
53
+ })
54
+ }
55
+
56
+ sendContactEmail = async (data) => {
57
+ return new Promise((resolve, reject) => {
58
+ let transport = nodemailer.createTransport(this.mailinfo.smtp);
59
+ const { $subject, $email, $message, $source } = data;
60
+
61
+ const options = {
62
+ from: $source,
63
+ to: this.email,
64
+ subject:"Contact Form :: " + $email,
65
+ text: $message,
66
+ }
67
+
68
+ transport.sendMail(options, (error, info) => {
69
+ console.log('send contact email resp :: ', error);
70
+
71
+ if (error) return reject({ message: `An error has occured: ${error}`});
72
+
73
+ return resolve({ message: 'Email sent succesfully!'})
74
+ })
75
+ })
76
+ }
77
+ }
@@ -0,0 +1,3 @@
1
+ module.exports = (theFunc) => (req, res, next) => {
2
+ Promise.resolve(theFunc(req, res, next)).catch(next);
3
+ };