Compare commits
1 commit
master
...
php-refact
Author | SHA1 | Date | |
---|---|---|---|
|
2de6589222 |
16 changed files with 355 additions and 2892 deletions
|
@ -1,2 +0,0 @@
|
||||||
node_modules
|
|
||||||
vendor
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
node_modules
|
node_modules
|
||||||
local.json
|
development.yml
|
||||||
development.json
|
production.yml
|
||||||
production.json
|
|
||||||
vendor
|
vendor
|
||||||
|
|
3
.jshintrc
Normal file
3
.jshintrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"esversion": 6
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
FROM node:14-alpine
|
|
||||||
WORKDIR /app
|
|
||||||
COPY . .
|
|
||||||
RUN npm ci
|
|
||||||
ENTRYPOINT [ "node", "index.js" ]
|
|
79
README.md
79
README.md
|
@ -6,22 +6,22 @@ A basic node server for sending email forms.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<form method="post" action="http://example.com/contact@example.com">
|
<form method="post" action="http://example.com/contact@example.com">
|
||||||
<input type="hidden" name="_subject" value="This is a test form" />
|
<input type="hidden" name="_subject" value="This is a test form" />
|
||||||
<input type="email" name="_from" />
|
<input type="email" name="_from" />
|
||||||
<input type="text" name="first_name" />
|
<input type="text" name="first_name" />
|
||||||
<input type="text" name="last_name" />
|
<input type="text" name="last_name" />
|
||||||
<textarea name="comments"></textarea>
|
<textarea name="comments"></textarea>
|
||||||
<input type="submit" name="Submit" />
|
<input type="submit" name="Submit" />
|
||||||
</form>
|
</form>
|
||||||
```
|
```
|
||||||
|
|
||||||
This project is, in some way, a clone of an excellent free service: [Formspree.io](https://formspree.io/). Although Formspree is outstanding, it might **not** be the best option for everyone; 2 key factors drove me to create this clone:
|
This project is, in some way, a clone of a great free service: [Formspree.io](https://formspree.io/). Although Formspree is great, it might **not** be the best option for everyone; 2 key factors drived me to create this clone:
|
||||||
|
|
||||||
1. Setup (and maintenance) should be minimal.
|
1. Setup (and maintenance) should be minimal.
|
||||||
Formspree is opensource, and its code is on GitHub, but the setup process is way more than a trivial task, not to mention the requirements. Requirement 1 not met.
|
Formspree is opensource and it's code is on GitHub, but the setup process is way more than a trivial task, not to mention the requirements. Requirement 1 not met.
|
||||||
|
|
||||||
1. Should allow me to send attachments.
|
1. Should allow me to send attachments.
|
||||||
Formspree does not allow you to send email forms with attachments (at least not at the time when this written). Requirement 2 not met.
|
Formspree does not allow you to send email forms with attachments (at least not at the time when this written). Requirement 2 not met.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
@ -32,39 +32,38 @@ This project is, in some way, a clone of an excellent free service: [Formspree.i
|
||||||
|
|
||||||
Clone this repo on your server or download the zip file.
|
Clone this repo on your server or download the zip file.
|
||||||
|
|
||||||
Once you have the code, run `npm install --production` to download and install all the project dependencies required to run this project.
|
Once you have the code, run `npn install --production` to download and install all the project dependencies required to run this project.
|
||||||
|
|
||||||
Next step, configure your server. Open `config/config.json` which should look like this:
|
Next step, configure your server. Open `config/config.yml` which should look like this:
|
||||||
|
|
||||||
```json
|
```yml
|
||||||
{
|
emails:
|
||||||
"emails": [],
|
mailgun:
|
||||||
"mailgun": {
|
url:
|
||||||
"url": "",
|
key:
|
||||||
"key": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
And update the values to match your preferences:
|
And update the values to match your preferences:
|
||||||
|
|
||||||
- **emails** is an array of email addresses. These emails are the **ONLY** emails this server will be allowed to send emails to (authorized emails)
|
- **emails** is an array of email addresses. This emails are the **ONLY** emails this server will be allowed to send emails to (authorized emails)
|
||||||
- **mailgun.url** your Mailgun API URL
|
- **mailgun.url** your Mailgun API URL
|
||||||
- **mailgun.key** you Mailgun Domain API Key
|
- **mailgun.key** you Mailgun Domain API Key
|
||||||
|
|
||||||
An example of a `config.json` file:
|
An example of a `config.yml` file:
|
||||||
|
|
||||||
```json
|
```yml
|
||||||
{
|
emails:
|
||||||
"emails": ["sales@example.com", "contact@example.com", "support@example.com"],
|
- sales@example.com
|
||||||
"mailgun": {
|
- contact@example.com
|
||||||
"url": "https://api.mailgun.net/v3/example.com/messages",
|
- support@example.com
|
||||||
"key": "key-l0r3m1p5umd0l0r5174m37c0n53c737u"
|
mailgun:
|
||||||
}
|
url: https://api.mailgun.net/v3/example.com/messages
|
||||||
}
|
key: key-l0r3m1p5umd0l0r5174m37c0n53c737u
|
||||||
```
|
```
|
||||||
|
|
||||||
**Contact** uses `NODE_ENV` environment variable for loading its JSON configuration files, this allows you to override the above settings with other JSON files, for example, `config/production.json`.
|
**Contact** uses [indecent.js][indecent] for loading its YAML configuration files, this allows you to override the above settings based on the value of `NODE_ENV`. You can read more about that in the [module documentation][indecent].
|
||||||
|
|
||||||
|
[indecent]: https://github.com/eruizdechavez/indecent.js
|
||||||
|
|
||||||
## Server Usage
|
## Server Usage
|
||||||
|
|
||||||
|
@ -74,15 +73,15 @@ To run the server, just run `node index.js`. You can use other node runners to k
|
||||||
|
|
||||||
Once your server is up and running, all you need to do is create an HTML form and point it to your server.
|
Once your server is up and running, all you need to do is create an HTML form and point it to your server.
|
||||||
|
|
||||||
Your form's action should point to your **contact** server using a valid email address (defined in the YAML file). If the email address is not in the whitelist, the email will not be sent.
|
Your form's action should point to your **contact** server using a valid email address (defined in the YAML file). If the email address is not in the whitelist the email will not be sent.
|
||||||
|
|
||||||
### Fields
|
### Fields
|
||||||
|
|
||||||
- **\_from**: _Required_. This is usually the email address of the user submitting the email form. It will be used as the Form field.
|
- **_from**: *Required*. This is usually the email address of the user submitting the email form. It will be used as the Form field.
|
||||||
- **\_subject**: _Optional_. The email subject.
|
- **_subject**: *Optional*. The email subject.
|
||||||
- **\_info**: _Optional_. This text will be included in the email body before the values. Useful for providing some context in the email body.
|
- **_info**: *Optional*. This text will be included in the email body before the values. Useful for providing some context in the email body.
|
||||||
- **\_attachment**: _Optional_. A file can be attached to the email form using this for the name of an `<input type="file"/>`. When sending attachments do not forget to include `enctype="multipart/form-data"` in your form tag.
|
- **_attachment**: *Optional*. A file can be attached to the email form using this for the name of an `<input type="file"/>`. When sending attachments do not forget to include `enctype="multipart/form-data"` in your form tag.
|
||||||
- **\_next**: _Optional_. A URL to redirect the user once the form was submitted successfully.
|
- **_next**: *Optional*. A URL to redirect the user once the form was submited succesfully.
|
||||||
- **\_fake**: _For testing_. If `true`, the email will not be sent and instead a JSON payload will be shown. Useful when testing the form with a REST client.
|
- **_fake**: *For testing*. If `true`, the email will not be sent and instead a JSON paylod will be shown. Useful when testing the form with a REST client.
|
||||||
|
|
||||||
All other form fields will be sent by title casing the name. For example `<input type="text" name="first_name" />` will be displayed in the email as "First Name:"
|
All other form fields will be send by title casing the name. For example `<input type="text" name="first_name" />` will be displayed in the email as "First Name:"
|
||||||
|
|
6
composer.json
Normal file
6
composer.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"rmccue/requests": "^1.7",
|
||||||
|
"xamin/handlebars.php": "^0.10.4"
|
||||||
|
}
|
||||||
|
}
|
109
composer.lock
generated
Normal file
109
composer.lock
generated
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "a54bd6daf1501e5092742fd20e496fec",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "rmccue/requests",
|
||||||
|
"version": "v1.7.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/rmccue/Requests.git",
|
||||||
|
"reference": "87932f52ffad70504d93f04f15690cf16a089546"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/rmccue/Requests/zipball/87932f52ffad70504d93f04f15690cf16a089546",
|
||||||
|
"reference": "87932f52ffad70504d93f04f15690cf16a089546",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"requests/test-server": "dev-master"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Requests": "library/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"ISC"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ryan McCue",
|
||||||
|
"homepage": "http://ryanmccue.info"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A HTTP library written in PHP, for human beings.",
|
||||||
|
"homepage": "http://github.com/rmccue/Requests",
|
||||||
|
"keywords": [
|
||||||
|
"curl",
|
||||||
|
"fsockopen",
|
||||||
|
"http",
|
||||||
|
"idna",
|
||||||
|
"ipv6",
|
||||||
|
"iri",
|
||||||
|
"sockets"
|
||||||
|
],
|
||||||
|
"time": "2016-10-13T00:11:37+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "xamin/handlebars.php",
|
||||||
|
"version": "v0.10.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/XaminProject/handlebars.php.git",
|
||||||
|
"reference": "b85cee07eae96db0e1eec224ca90f5ce1e4d857a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/XaminProject/handlebars.php/zipball/b85cee07eae96db0e1eec224ca90f5ce1e4d857a",
|
||||||
|
"reference": "b85cee07eae96db0e1eec224ca90f5ce1e4d857a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.4",
|
||||||
|
"squizlabs/php_codesniffer": "~1.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Handlebars": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "fzerorubigd",
|
||||||
|
"email": "fzerorubigd@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Behrooz Shabani (everplays)",
|
||||||
|
"email": "everplays@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Handlebars processor for php",
|
||||||
|
"homepage": "https://github.com/XaminProject/handlebars.php",
|
||||||
|
"time": "2016-12-12T13:51:02+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
BIN
composer.phar
Executable file
BIN
composer.phar
Executable file
Binary file not shown.
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"emails": [],
|
|
||||||
"mailgun": {
|
|
||||||
"url": "",
|
|
||||||
"key": ""
|
|
||||||
}
|
|
||||||
}
|
|
4
config/config.yml
Normal file
4
config/config.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
emails:
|
||||||
|
mailgun:
|
||||||
|
url:
|
||||||
|
key:
|
|
@ -1,13 +0,0 @@
|
||||||
services:
|
|
||||||
node:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- 8081:8081
|
|
||||||
networks:
|
|
||||||
- palmiers
|
|
||||||
|
|
||||||
networks:
|
|
||||||
palmiers:
|
|
||||||
external: true
|
|
|
@ -1,34 +1,31 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
<head>
|
<meta charset="utf-8">
|
||||||
<meta charset="utf-8">
|
<style media="screen">
|
||||||
<style media="screen">
|
th {
|
||||||
th {
|
text-align: right;
|
||||||
text-align: right;
|
font-weight: bold;
|
||||||
font-weight: bold;
|
}
|
||||||
}
|
</style>
|
||||||
</style>
|
</head>
|
||||||
</head>
|
<body>
|
||||||
|
<p>{{info}}</p>
|
||||||
<body>
|
<table>
|
||||||
<p>{{info}}</p>
|
<tbody>
|
||||||
<table>
|
{{#data}}
|
||||||
<tbody>
|
<tr>
|
||||||
{{#data}}
|
<th>
|
||||||
<tr>
|
{{key}}:
|
||||||
<th>
|
</th>
|
||||||
{{key}}:
|
<td>
|
||||||
</th>
|
{{value}}
|
||||||
<td>
|
</td>
|
||||||
{{value}}
|
</tr>
|
||||||
</td>
|
{{/data}}
|
||||||
</tr>
|
</tbody>
|
||||||
{{/data}}
|
</table>
|
||||||
</tbody>
|
<p> </p>
|
||||||
</table>
|
<p> </p>
|
||||||
<p> </p>
|
</body>
|
||||||
<p> </p>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
199
index.js
199
index.js
|
@ -3,38 +3,27 @@ const restify = require('restify');
|
||||||
const Handlebars = require('handlebars');
|
const Handlebars = require('handlebars');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const corsMiddleware = require('restify-cors-middleware');
|
const config = require('indecent');
|
||||||
const cors = corsMiddleware({
|
|
||||||
preflightMaxAge: 5,
|
|
||||||
origins: ['*'],
|
|
||||||
});
|
|
||||||
const { chain, get, indexOf, merge, set, startCase } = require('lodash');
|
const { chain, get, indexOf, merge, set, startCase } = require('lodash');
|
||||||
|
|
||||||
let defaults;
|
|
||||||
try {
|
|
||||||
defaults = JSON.parse(fs.readFileSync(path.join(__dirname, 'config', 'config.json'), { encoding: 'utf8' }));
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err.message);
|
|
||||||
defaults = {};
|
|
||||||
}
|
|
||||||
let environment;
|
|
||||||
|
|
||||||
try {
|
|
||||||
environment = JSON.parse(
|
|
||||||
fs.readFileSync(path.join(__dirname, 'config', `${process.env.NODE_ENV}.json`), { encoding: 'utf8' })
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err.message);
|
|
||||||
environment = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = merge(defaults, environment);
|
|
||||||
const knownEmails = get(config, 'emails');
|
const knownEmails = get(config, 'emails');
|
||||||
|
|
||||||
const MAILGUN_URL = get(config, 'mailgun.url');
|
const MAILGUN_URL = get(config, 'mailgun.url');
|
||||||
const MAILGUN_API_KEY = get(config, 'mailgun.key');
|
const MAILGUN_API_KEY = get(config, 'mailgun.key');
|
||||||
|
|
||||||
const FORM_FIELDS = ['_from', '_subject', '_to', '_attachment'];
|
const FORM_FIELDS = [
|
||||||
const PRIVATE_FIELDS = ['_fake', '_info', '_next'];
|
'_from',
|
||||||
|
'_subject',
|
||||||
|
'_to',
|
||||||
|
'_attachment'
|
||||||
|
];
|
||||||
|
|
||||||
|
const PRIVATE_FIELDS = [
|
||||||
|
'_fake',
|
||||||
|
'_info',
|
||||||
|
'_next'
|
||||||
|
];
|
||||||
|
|
||||||
const htmlSource = fs.readFileSync(path.join(__dirname, 'html_template.hbs'), { encoding: 'utf8' });
|
const htmlSource = fs.readFileSync(path.join(__dirname, 'html_template.hbs'), { encoding: 'utf8' });
|
||||||
const textSource = fs.readFileSync(path.join(__dirname, 'text_template.hbs'), { encoding: 'utf8' });
|
const textSource = fs.readFileSync(path.join(__dirname, 'text_template.hbs'), { encoding: 'utf8' });
|
||||||
|
@ -42,113 +31,105 @@ const htmlTemplate = Handlebars.compile(htmlSource);
|
||||||
const textTemplate = Handlebars.compile(textSource);
|
const textTemplate = Handlebars.compile(textSource);
|
||||||
|
|
||||||
var server = restify.createServer();
|
var server = restify.createServer();
|
||||||
server.pre(cors.preflight);
|
server.use(restify.CORS());
|
||||||
server.use(cors.actual);
|
server.use(restify.bodyParser());
|
||||||
server.use(
|
|
||||||
restify.plugins.bodyParser({
|
|
||||||
mapParams: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
server.get('/status', (req, res, next) => {
|
server.get('/status', (req, res, next) => {
|
||||||
res.send('contact running');
|
res.send('contact running');
|
||||||
return next();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.post('/:_to', (req, res, next) => {
|
server.post('/:_to', (req, res, next) => {
|
||||||
const { formData, fields } = parseRequest(req);
|
const { formData, fields } = parseRequest(req);
|
||||||
|
|
||||||
if (indexOf(knownEmails, get(formData, 'to')) < 0) {
|
if (indexOf(knownEmails, get(formData, 'to')) < 0) {
|
||||||
return next(new Error('Unknown email address'));
|
return next(new Error('Unknown email address'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
formData,
|
formData,
|
||||||
auth: {
|
auth: {
|
||||||
user: 'api',
|
user: 'api',
|
||||||
pass: MAILGUN_API_KEY,
|
pass: MAILGUN_API_KEY
|
||||||
},
|
},
|
||||||
url: MAILGUN_URL,
|
url: MAILGUN_URL,
|
||||||
method: 'post',
|
method: 'post'
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMail(fields, params)
|
sendMail(fields, params).then(response => {
|
||||||
.then(response => {
|
const redirect = get(fields, 'next');
|
||||||
const redirect = get(fields, 'next');
|
if (redirect) {
|
||||||
if (redirect) {
|
res.redirect(redirect, next);
|
||||||
res.redirect(redirect, next);
|
} else {
|
||||||
} else {
|
res.json(response);
|
||||||
res.json(response);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
})
|
}).catch(error => {
|
||||||
.catch(error => {
|
return next(error);
|
||||||
return next(error);
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function parseRequest(req) {
|
function parseRequest (req) {
|
||||||
const body = get(req, 'params');
|
const body = get(req, 'params');
|
||||||
|
|
||||||
const formData = chain(body)
|
const formData = chain(body)
|
||||||
.pick(FORM_FIELDS)
|
.pick(FORM_FIELDS)
|
||||||
.mapKeys((value, key) => key.replace('_', ''))
|
.mapKeys((value, key) => key.replace('_', ''))
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
const fields = chain(body)
|
const fields = chain(body)
|
||||||
.pick(PRIVATE_FIELDS)
|
.pick(PRIVATE_FIELDS)
|
||||||
.mapKeys((value, key) => key.replace('_', ''))
|
.mapKeys((value, key) => key.replace('_', ''))
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
const data = chain(body)
|
const data = chain(body)
|
||||||
.omit(PRIVATE_FIELDS)
|
.omit(PRIVATE_FIELDS)
|
||||||
.omit(FORM_FIELDS)
|
.omit(FORM_FIELDS)
|
||||||
.mapKeys((value, key) => startCase(key))
|
.mapKeys((value, key) => startCase(key))
|
||||||
.map((value, key) => {
|
.map((value, key) => {
|
||||||
return { key, value };
|
return { key, value };
|
||||||
})
|
})
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
set(fields, 'data', data);
|
set(fields, 'data', data);
|
||||||
set(formData, 'html', htmlTemplate(fields));
|
set(formData, 'html', htmlTemplate(fields));
|
||||||
set(formData, 'text', textTemplate(fields));
|
set(formData, 'text', textTemplate(fields));
|
||||||
|
|
||||||
const attachment = get(req, 'files._attachment');
|
const attachment = get(req, 'files._attachment');
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
const filePath = get(attachment, 'path');
|
const filePath = get(attachment, 'path');
|
||||||
const value = get(fields, 'fake') ? filePath : fs.createReadStream(filePath);
|
const value = get(fields, 'fake') ? filePath : fs.createReadStream(filePath);
|
||||||
|
|
||||||
set(formData, 'attachment', {
|
set(formData, 'attachment', {
|
||||||
value,
|
value,
|
||||||
options: {
|
options: {
|
||||||
filename: get(attachment, 'name'),
|
filename: get(attachment, 'name'),
|
||||||
contentType: get(attachment, 'type'),
|
contentType: get(attachment, 'type')
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data, fields, formData };
|
return { data, fields, formData };
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMail(fields, params) {
|
function sendMail (fields, params) {
|
||||||
const fake = get(fields, 'fake');
|
const fake = get(fields, 'fake');
|
||||||
|
|
||||||
if (fake) {
|
if (fake) {
|
||||||
return Promise.resolve(merge({ message: 'fake response' }, params));
|
return Promise.resolve(merge({ message: 'fake response' }, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request(params, (error, msg, response) => {
|
request(params, (error, msg, response) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return reject(error);
|
return reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolve(JSON.parse(response));
|
return resolve(JSON.parse(response));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
server.listen(8081, () => {
|
server.listen(8081, () => {
|
||||||
console.log(`${server.name} listening at ${server.url}`);
|
console.log(`${server.name} listening at ${server.url}`);
|
||||||
});
|
});
|
||||||
|
|
46
index.php
Normal file
46
index.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
require_once './vendor/autoload.php';
|
||||||
|
// phpinfo();
|
||||||
|
|
||||||
|
// $response = Requests::get('https://api.github.com/events');
|
||||||
|
// var_dump(json_decode($response->body));
|
||||||
|
|
||||||
|
// var_dump($_GET);
|
||||||
|
// var_dump($_POST);
|
||||||
|
|
||||||
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
|
|
||||||
|
// if ($method == 'GET') {
|
||||||
|
// echo 'contact running';
|
||||||
|
// exit;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const FORM_FIELDS = [
|
||||||
|
'_from',
|
||||||
|
'_subject',
|
||||||
|
'_to',
|
||||||
|
'_attachment',
|
||||||
|
];
|
||||||
|
|
||||||
|
const PRIVATE_FIELDS = [
|
||||||
|
'_fake',
|
||||||
|
'_info',
|
||||||
|
'_next',
|
||||||
|
];
|
||||||
|
|
||||||
|
$formData = [
|
||||||
|
'from' => $_POST['_from'],
|
||||||
|
'subject' => $_POST['_subject'],
|
||||||
|
'to' => $_POST['_to'],
|
||||||
|
'attachment' => $_POST['_attachment'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = [
|
||||||
|
'fake' => $_POST['_fake'],
|
||||||
|
'info' => $_POST['_info'],
|
||||||
|
'next' => $_POST['_next'],
|
||||||
|
];
|
||||||
|
|
||||||
|
var_dump($formData, $fields);
|
||||||
|
|
||||||
|
echo 'DONE';
|
2654
package-lock.json
generated
2654
package-lock.json
generated
File diff suppressed because it is too large
Load diff
54
package.json
54
package.json
|
@ -1,29 +1,29 @@
|
||||||
{
|
{
|
||||||
"name": "contact",
|
"name": "contact",
|
||||||
"version": "2.0.0",
|
"version": "1.0.1",
|
||||||
"description": "A basic clone of formspree.io for internal use",
|
"description": "A basic clone of formspree.io for internal use",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"homepage": "https://github.com/eruizdechavez/contact",
|
"homepage": "https://github.com/eruizdechavez/contact",
|
||||||
"bugs": "https://github.com/eruizdechavez/contact/issues",
|
"bugs": "https://github.com/eruizdechavez/contact/issues",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Erick Ruiz de Chavez",
|
"name": "Erick Ruiz de Chavez",
|
||||||
"email": "eruizdechavez@fastmail.com",
|
"email": "eruizdechavez@fastmail.com",
|
||||||
"url": "https://github.com/eruizdechavez"
|
"url": "https://github.com/eruizdechavez"
|
||||||
},
|
},
|
||||||
"repository": "eruizdechavez/contact",
|
"repository": "eruizdechavez/contact",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"handlebars": "4.1.2",
|
"handlebars": "4.0.5",
|
||||||
"lodash": "4.17.11",
|
"indecent": "1.0.1",
|
||||||
"request": "2.88.0",
|
"lodash": "4.13.1",
|
||||||
"restify": "8.3.2",
|
"request": "2.72.0",
|
||||||
"restify-cors-middleware": "1.1.1"
|
"restify": "4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"semistandard": "*"
|
"semistandard": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue