form-to-mail 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of form-to-mail might be problematic. Click here for more details.

package/.env.sample ADDED
@@ -0,0 +1,22 @@
1
+ # This is a sample .env file for use in local development.
2
+ # Duplicate this file as .env in the root of the project
3
+ # and update the environment variables to match your
4
+ # desired config
5
+ #
6
+ # See the README for full descriptions of each of the
7
+ # available configurations.
8
+
9
+ #Node
10
+ NODE_ENV=
11
+
12
+ # SMTP
13
+ SMTP_HOST=
14
+ SMTP_PORT=
15
+ SMTP_USER=
16
+ SMTP_PASSWORD=
17
+
18
+ #Mail Options
19
+ MAIL_FROM_NAME=
20
+ MAIL_FROM_EMAIL=
21
+ MAIL_TO_NAME=
22
+ MAIL_TO_EMAIL=
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # Form To Mail
2
+
3
+ Form To mail is a simple way to receive emails ✉ from contact forms on your website. Which handles files uploads on the fly for you Out of the box itself.
4
+ Just Plugin the formToMail middleware and setup the .env variable's. You are good to go.
5
+
6
+ In development test SMTP service account from ethereal.email are generated and Preview URL's are logged. you can visit them to view the emails.
7
+
8
+ ## Getting Started
9
+
10
+ ## 1. Install
11
+
12
+ ```bash
13
+ npm install form-to-mail
14
+ ```
15
+
16
+ ## 2. Setup SMTP and Mail Options
17
+
18
+ Create a `.env` file in the root of your project with below environmental variables and fill them with your credentials.
19
+
20
+ ```dosini
21
+ # SMTP
22
+ SMTP_HOST=
23
+ SMTP_PORT=
24
+ SMTP_USER=
25
+ SMTP_PASSWORD=
26
+
27
+ #Mail Options
28
+ MAIL_FROM_NAME=
29
+ MAIL_FROM_EMAIL=
30
+ MAIL_TO_NAME=
31
+ MAIL_TO_EMAIL=
32
+ ```
33
+ ## Example
34
+
35
+ Suppose you have this HTML from in your contact page.Set the form action URL to your Custom endpoint.
36
+
37
+ contact-form.html
38
+ ```html
39
+ <form action="/" method="POST">
40
+
41
+ <div>
42
+ <label for="name" class="form-label"> Full Name </label>
43
+ <input type="text" name="name" id="name" placeholder="Full Name" class="form-input" />
44
+ </div>
45
+
46
+ <div>
47
+ <label for="email" class="form-label"> Email Address </label>
48
+ <input type="email" name="email" id="email" placeholder="Enter your email" class="form-input"/>
49
+ </div>
50
+
51
+ <div>
52
+ <label for="subject" class="form-label"> Subject </label>
53
+ <input type="text" name="subject" id="subject" placeholder="Enter your subject" class="form-input"/>
54
+ </div>
55
+
56
+ <div class="mb-5">
57
+ <label for="message" class="form-label"> Message </label>
58
+ <textarea rows="6" name="message" id="message" placeholder="Type your message" class="form-input"></textarea>
59
+ </div>
60
+
61
+ <div>
62
+ <button class="form-btn">Submit</button>
63
+ </div>
64
+
65
+ </form>
66
+ ```
67
+ ## 3. Create a express app
68
+ creates the routes for the POST endpoint. and add formToEmail middleware which will handle the form submission for you.
69
+ After that you can redirect the users to a confirmation / thank you page or you cloud send a custom response.
70
+ ```js
71
+ const express = require('express')
72
+ const app = express()
73
+ const port = 3000
74
+ const formToMail = require('form-to-mail')
75
+
76
+
77
+ app.get('/', (req, res) => res.sendFile('contact-form.html'))
78
+ app.get('/thank-you', (req, res) => res.sendFile('thank-you.html'))
79
+
80
+ // POST endpoint
81
+ app.post('/',formToMail, (req, res) => {
82
+ res.redirect(303, '/thank-you');
83
+ })
84
+
85
+ app.listen(port, () => console.log(`listening on port ${port}!`))
86
+ ```
87
+ Sample Form Submission
88
+
89
+ ![Sample Form Submission](/images/form-submission.jpeg)
90
+
91
+ You can find the sample Contact and Thank you pages inside the test folder.
92
+
93
+
94
+ <!-- CONTRIBUTING -->
95
+ ## Contributing
96
+
97
+ Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
98
+
99
+ If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
100
+ Don't forget to give the project a star! Thanks again!
101
+
102
+ 1. Fork the Project
103
+ 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
104
+ 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
105
+ 4. Push to the Branch (`git push origin feature/AmazingFeature`)
106
+ 5. Open a Pull Request
package/app.js ADDED
@@ -0,0 +1,21 @@
1
+ const formidable = require('formidable')
2
+ const mailer = require('./modules/mailer.js')
3
+
4
+ const formMailer = (req, res, next) => {
5
+
6
+ const form = formidable({ multiples: true });
7
+
8
+ form.parse(req, async(err, fields, files) => {
9
+ if (err) {
10
+ next(err);
11
+ return;
12
+ }
13
+ req.fields = fields;
14
+ req.files = files;
15
+ await mailer(req.fields,req.files)
16
+ next();
17
+
18
+ });
19
+ };
20
+
21
+ module.exports = formMailer
Binary file
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ const nodemailer = require('nodemailer')
3
+ const dotenv = require('dotenv')
4
+ dotenv.config()
5
+
6
+ const getSMTPCredientails = () => {
7
+
8
+ const SMTP = {
9
+ host: process.env.SMTP_HOST,
10
+ port: process.env.SMTP_PORT,
11
+ user: process.env.SMTP_USER,
12
+ password: process.env.SMTP_PASSWORD
13
+ }
14
+ return SMTP
15
+ }
16
+
17
+ const createTestTransport = (testAccount) => {
18
+
19
+ // create reusable transporter object using the default SMTP transport
20
+ const transporter = nodemailer.createTransport({
21
+ host: "smtp.ethereal.email",
22
+ port: 587,
23
+ secure: false, // true for 465, false for other ports
24
+ auth: {
25
+ user: testAccount.user, // generated ethereal user
26
+ pass: testAccount.pass, // generated ethereal password
27
+ },
28
+ });
29
+ return transporter
30
+ }
31
+
32
+ const createTransport = () => {
33
+
34
+ const SMTP = getSMTPCredientails()
35
+ const transporter = nodemailer.createTransport({
36
+ host: SMTP.host,
37
+ port: SMTP.port || 587,
38
+ secure: SMTP.port === 465, // true for 465, false for other ports
39
+ auth: {
40
+ user: SMTP.user,
41
+ pass: SMTP.password,
42
+ },
43
+ })
44
+ return transporter
45
+ }
46
+
47
+ const getTransporter = (testAccount) => {
48
+ if(process.env.NODE_ENV === 'production') return createTransport()
49
+ return createTestTransport(testAccount)
50
+ }
51
+
52
+ const mailer = async (fields,files) => {
53
+
54
+ // Generate test SMTP service account from ethereal.email
55
+ // Only needed if you don't have a real mail account for testing
56
+ let testAccount
57
+ if(process.env.NODE_ENV !== 'production') {
58
+ testAccount = await nodemailer.createTestAccount()
59
+ console.log('testAccount: ', testAccount)
60
+ }
61
+
62
+ let transporter = getTransporter(testAccount)
63
+
64
+ const mailFromName = process.env.MAIL_FROM_NAME
65
+ const mailFrom = process.env.MAIL_FROM_EMAIL
66
+ const mailToName = process.env.MAIL_TO_NAME
67
+ const mailTo = process.env.MAIL_TO_EMAIL
68
+
69
+ let attachments = []
70
+ Object.entries(files).forEach(([file, value]) => {
71
+ attachments.push({
72
+ path:file
73
+ })
74
+ })
75
+
76
+ let submissionFields=''
77
+ Object.entries(fields).forEach(([filed, value]) => {
78
+ let capitalizefirstLetter= filed.charAt(0).toUpperCase()+ filed.slice(1)
79
+ submissionFields+=`<p><b>${capitalizefirstLetter}:</b> ${value}</p>`
80
+ })
81
+
82
+ const mailSubject = fields.subject ? fields.subject : "New submission"
83
+
84
+ // send mail with defined transport object
85
+ let email = await transporter.sendMail({
86
+ from: `${mailFromName} <${mailFrom}>`, // sender address
87
+ to: mailTo, // list of receivers
88
+ subject: mailSubject, // Subject line
89
+ html:`<p>Hola ${mailToName}, </p>
90
+ <p>You have a new submission on from Contact form.</p>
91
+ <p style="color: #999999;"><strong>SUBMISSION<strong></p>
92
+ ${submissionFields}
93
+ `, // html body
94
+ attachments:attachments
95
+ });
96
+
97
+ console.log("Message sent: %s", email.messageId);
98
+ // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
99
+
100
+ // Preview only available when sending through an Ethereal account
101
+ console.log("Preview URL: %s", nodemailer.getTestMessageUrl(email))
102
+ // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
103
+
104
+ }
105
+
106
+ module.exports=mailer
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "form-to-mail",
3
+ "version": "1.0.0",
4
+ "description": "A Simple Form Mailer. ✉",
5
+ "main": "app.js",
6
+ "scripts": {
7
+ "test": "node test/test.js"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/LazyFolks/form-to-mail.git"
12
+ },
13
+ "keywords": [
14
+ "email",
15
+ "email-sender",
16
+ "form-to-mail",
17
+ "form-mail",
18
+ "form-mailer",
19
+ "formtoemail"
20
+ ],
21
+ "author": "Karthik",
22
+ "license": "ISC",
23
+ "bugs": {
24
+ "url": "https://github.com/LazyFolks/form-to-mail/issues"
25
+ },
26
+ "homepage": "https://github.com/LazyFolks/form-to-mail#readme",
27
+ "dependencies": {
28
+ "dotenv": "^16.0.3",
29
+ "formidable": "^2.0.1",
30
+ "form-to-mail": "^1.0.0",
31
+ "nodemailer": "^6.8.0"
32
+ },
33
+ "directories": {
34
+ "test": "test"
35
+ },
36
+ "devDependencies": {
37
+ "express": "^4.18.2"
38
+ }
39
+ }
@@ -0,0 +1,129 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Contact Form</title>
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+ body {
15
+ font-family: 'Source Sans Pro', sans-serif;
16
+ }
17
+ .mb-5 {
18
+ margin-bottom: 20px;
19
+ }
20
+ .form-main-wrapper {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ padding: 48px;
25
+ }
26
+ .form-wrapper {
27
+ margin: 0 auto;
28
+ max-width: 550px;
29
+ width: 100%;
30
+ background: white;
31
+ }
32
+ .form-label {
33
+ display: block;
34
+ font-weight: 500;
35
+ font-size: 16px;
36
+ color: #07074d;
37
+ margin-bottom: 12px;
38
+ }
39
+ .form-input {
40
+ width: 100%;
41
+ padding: 12px 24px;
42
+ border-radius: 6px;
43
+ border: 1px solid #e0e0e0;
44
+ background: white;
45
+ font-weight: 500;
46
+ font-size: 16px;
47
+ color: #6b7280;
48
+ outline: none;
49
+ resize: none;
50
+ }
51
+ .form-input:focus {
52
+ border-color: #5892FF;
53
+ box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.05);
54
+ }
55
+
56
+ .form-btn {
57
+ text-align: center;
58
+ font-size: 16px;
59
+ border-radius: 6px;
60
+ padding: 14px 32px;
61
+ border: none;
62
+ font-weight: 600;
63
+ background-color: #5892FF;
64
+ color: white;
65
+ cursor: pointer;
66
+ }
67
+ .form-btn:hover {
68
+ box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.05);
69
+ }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <main>
74
+ <div class="form-main-wrapper">
75
+ <div class="form-wrapper">
76
+ <form action="/" method="POST">
77
+ <div class="mb-5">
78
+ <label for="name" class="form-label"> Full Name </label>
79
+ <input
80
+ type="text"
81
+ name="name"
82
+ id="name"
83
+ placeholder="Full Name"
84
+ class="form-input"
85
+ />
86
+ </div>
87
+
88
+ <div class="mb-5">
89
+ <label for="email" class="form-label"> Email Address </label>
90
+ <input
91
+ type="email"
92
+ name="email"
93
+ id="email"
94
+ placeholder="Enter your email"
95
+ class="form-input"
96
+ />
97
+ </div>
98
+
99
+ <div class="mb-5">
100
+ <label for="subject" class="form-label"> Subject </label>
101
+ <input
102
+ type="text"
103
+ name="subject"
104
+ id="subject"
105
+ placeholder="Enter your subject"
106
+ class="form-input"
107
+ />
108
+ </div>
109
+
110
+ <div class="mb-5">
111
+ <label for="message" class="form-label"> Message </label>
112
+ <textarea
113
+ rows="6"
114
+ name="message"
115
+ id="message"
116
+ placeholder="Type your message"
117
+ class="form-input"
118
+ ></textarea>
119
+ </div>
120
+
121
+ <div>
122
+ <button class="form-btn">Submit</button>
123
+ </div>
124
+ </form>
125
+ </div>
126
+ </div>
127
+ </main>
128
+ </body>
129
+ </html>
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Thank you !</title>
8
+ <style>
9
+ *{
10
+ box-sizing:border-box;
11
+ }
12
+ body{
13
+ background: #ffffff;
14
+ background: linear-gradient(to bottom, #ffffff 0%,#e1e8ed 100%);
15
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e1e8ed',GradientType=0 );
16
+ height: 100%;
17
+ margin: 0;
18
+ background-repeat: no-repeat;
19
+ background-attachment: fixed;
20
+
21
+ }
22
+ .parent-wrapper{
23
+ width:100%;
24
+ height:100vh;
25
+ display: flex;
26
+ flex-direction: column;
27
+ }
28
+ .child-wrapper{
29
+ padding :30px;
30
+ text-align:center;
31
+ }
32
+ h1{
33
+ font-family: 'Kaushan Script', cursive;
34
+ font-size:4em;
35
+ letter-spacing:3px;
36
+ color:#5892FF ;
37
+ margin:0;
38
+ margin-bottom:20px;
39
+ }
40
+ .child-wrapper p{
41
+ margin:0;
42
+ font-size:1.3em;
43
+ color:#aaa;
44
+ font-family: 'Source Sans Pro', sans-serif;
45
+ letter-spacing:1px;
46
+ }
47
+ .go-home{
48
+ color:#fff;
49
+ background:#5892FF;
50
+ border:none;
51
+ padding:10px 50px;
52
+ margin:30px 0;
53
+ border-radius:30px;
54
+ text-transform:capitalize;
55
+ box-shadow: 0 10px 16px 1px rgba(174, 199, 251, 1);
56
+ cursor:pointer;
57
+ }
58
+ .footer-wrapper{
59
+ margin-top: auto;
60
+ background:#D7E6FE;
61
+ padding:6px;
62
+ text-align:center;
63
+ }
64
+ .footer-wrapper p{
65
+ margin:0;
66
+ padding:4px;
67
+ color:#5892FF;
68
+ font-family: 'Source Sans Pro', sans-serif;
69
+ letter-spacing:1px;
70
+ }
71
+ .footer-wrapper p a{
72
+ text-decoration:none;
73
+ color:#5892FF;
74
+ font-weight:600;
75
+ }
76
+
77
+ @media (min-width:360px){
78
+ h1{
79
+ font-size:4.5em;
80
+ }
81
+ .go-home{
82
+ margin-bottom:20px;
83
+ }
84
+ }
85
+
86
+ @media (min-width:600px){
87
+ .content{
88
+ max-width:1000px;
89
+ margin:0 auto;
90
+ }
91
+ .parent-wrapper{
92
+ height: initial;
93
+ max-width:620px;
94
+ margin:0 auto;
95
+ margin-top:50px;
96
+ box-shadow: 4px 8px 40px 8px rgba(88, 146, 255, 0.2);
97
+ }
98
+ }
99
+ </style>
100
+ </head>
101
+ <body>
102
+ <main>
103
+ <div class=content>
104
+ <div class="parent-wrapper">
105
+ <div class="child-wrapper">
106
+ <h1>Thank you !</h1>
107
+ <p>we will get in touch with you as soon as possible and</p>
108
+ <p>you should receive a confirmation email soon.</p>
109
+ <button class="go-home" onclick="history.back()">
110
+ go back
111
+ </button>
112
+ </div>
113
+ <div class="footer-wrapper">
114
+ <p>Email not received?
115
+ <a href="#" onclick="history.back()">Click here to send again</a>
116
+ </p>
117
+ </div>
118
+ </div>
119
+ </div>
120
+
121
+ </main>
122
+ </body>
123
+ </html>
package/test/test.js ADDED
@@ -0,0 +1,18 @@
1
+ const express = require('express')
2
+ const app = express()
3
+ const port = 3000
4
+ const formToMail = require('form-to-mail')
5
+
6
+ const path = require('path')
7
+ const pages = '/pages'
8
+
9
+
10
+ app.get('/', (req, res) => res.sendFile(path.join(__dirname, pages, 'contact-form.html')))
11
+ app.get('/thank-you', (req, res) => res.sendFile(path.join(__dirname,pages, 'thank-you.html')))
12
+
13
+ app.post('/',formToMail, (req, res) => {
14
+ res.redirect(303, '/thank-you');
15
+ })
16
+
17
+
18
+ app.listen(port, () => console.log(`listening on port ${port}!`))