Removed hcaptcha
parent
33be91e6d5
commit
839ea3799a
|
@ -1,5 +1,4 @@
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
.c9/
|
|
||||||
.env
|
.env
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
docker-compose.yml
|
|
||||||
.c9/
|
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
docker-compose.yml
|
||||||
.env
|
.env
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This is a PGP-enabled contact form that you can use. It has two parts:
|
This is a PGP-enabled contact form that you can use. It has two parts:
|
||||||
|
|
||||||
- A static web form that uses javascript to encrypt a message and send it to an api endpoint
|
- A static web form that uses javascript to encrypt a message and send it to an api endpoint
|
||||||
- An API which checks the captcha and sends the message by email
|
- An API which sends the message by email
|
||||||
|
|
||||||
## Setting up a server
|
## Setting up a server
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ services:
|
||||||
container_name: mailapi
|
container_name: mailapi
|
||||||
environment:
|
environment:
|
||||||
- PORT=8080
|
- PORT=8080
|
||||||
- HCAPTCHA_SECRET=0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
||||||
- MAIL_FROM="My contact form <mailer@myserver.tld>"
|
- MAIL_FROM="My contact form <mailer@myserver.tld>"
|
||||||
- MAIL_TO=me@myserver.tld
|
- MAIL_TO=me@myserver.tld
|
||||||
- MAIL_SERVER=mail.myserver.tld
|
- MAIL_SERVER=mail.myserver.tld
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
<p><input type="text" id="subject-input" placeholder="Subject"></p>
|
<p><input type="text" id="subject-input" placeholder="Subject"></p>
|
||||||
<p><textarea id="message-input" placeholder="Your message"></textarea></p>
|
<p><textarea id="message-input" placeholder="Your message"></textarea></p>
|
||||||
|
|
||||||
<p><button id="send-button" class="h-captcha" data-sitekey="<YOUR HCAPTCHA SITE KEY>" data-callback="sendClicked">Send</button></p>
|
<p><button id="send-button">Send</button></p>
|
||||||
|
|
||||||
<p>This page is protected by <a href="https://www.hcaptcha.com/">hCaptcha</a> so its <a href="https://hcaptcha.com/privacy">Privacy Policy</a> and <a href="https://hcaptcha.com/terms">Terms of Service</a> apply.</p>
|
|
||||||
|
|
||||||
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
|
||||||
<script src="/PATH/TO/LOCAL/COPY/OF/openpgp.min.js"></script>
|
<script src="/PATH/TO/LOCAL/COPY/OF/openpgp.min.js"></script>
|
||||||
<script>/* global openpgp fetch */
|
<script>/* global openpgp fetch */
|
||||||
let send = document.getElementById('send-button')
|
let send = document.getElementById('send-button')
|
||||||
|
@ -22,53 +20,48 @@
|
||||||
|
|
||||||
const API_URL = "https://mailapi.mydomain.tld/"
|
const API_URL = "https://mailapi.mydomain.tld/"
|
||||||
|
|
||||||
async function sendClicked (captchaToken) {
|
async function sendClicked () {
|
||||||
if (captchaToken) {
|
send.disabled = true
|
||||||
send.disabled = true
|
send.innerHTML = `Sending... `
|
||||||
send.innerHTML = `Sending... `
|
let res; try {
|
||||||
let res; try {
|
res = await fetch(API_URL, {
|
||||||
res = await fetch(API_URL, {
|
method: 'POST',
|
||||||
method: 'POST',
|
// cache: 'no-cache',
|
||||||
// cache: 'no-cache',
|
headers: {'content-type': 'application/json'},
|
||||||
headers: {'content-type': 'application/json'},
|
body: JSON.stringify({
|
||||||
body: JSON.stringify({
|
name: name.value,
|
||||||
token: captchaToken,
|
subj: subj.value,
|
||||||
name: name.value,
|
email: email.value,
|
||||||
subj: subj.value,
|
msg: await openpgp.encrypt({
|
||||||
email: email.value,
|
message: await openpgp.createMessage(
|
||||||
msg: await openpgp.encrypt({
|
{ text: `${text.value}\n` }
|
||||||
message: await openpgp.createMessage(
|
),
|
||||||
{ text: `${text.value}\n` }
|
encryptionKeys: await openpgp.readKey({
|
||||||
),
|
armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
encryptionKeys: await openpgp.readKey({
|
|
||||||
armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
||||||
|
|
||||||
mQGNBF/TtIoBDADvYLnftyJjfWoeK0zE3Yh3jYsuAj27aU039xh6VaX0IsXQqKLD
|
mQGNBF/TtIoBDADvYLnftyJjfWoeK0zE3Yh3jYsuAj27aU039xh6VaX0IsXQqKLD
|
||||||
...
|
...
|
||||||
lk6lY0ktTb+vRnndyN3m+XW1mYdv3xUZMjQwMBtgdZbfY43pq8+N55tSTycF
|
lk6lY0ktTb+vRnndyN3m+XW1mYdv3xUZMjQwMBtgdZbfY43pq8+N55tSTycF
|
||||||
=Wvbt
|
=Wvbt
|
||||||
-----END PGP PUBLIC KEY BLOCK-----`,
|
-----END PGP PUBLIC KEY BLOCK-----`,
|
||||||
}),
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
}),
|
||||||
} catch (err) {
|
})
|
||||||
send.disabled = false
|
} catch (err) {
|
||||||
console.error(err)
|
|
||||||
alert('Failed to connect to the network. Are you online?')
|
|
||||||
}
|
|
||||||
console.log(res.json())
|
|
||||||
send.disabled = false
|
send.disabled = false
|
||||||
|
console.error(err)
|
||||||
if (res.status===200) {
|
alert('Failed to connect to the network. Are you online?')
|
||||||
text.value = ''; subj.value = ''; name.value = ''; email.value = ''
|
|
||||||
alert(Sent!')
|
|
||||||
} else if (res.status===403)
|
|
||||||
alert('hCaptcha failed! Please try again.')
|
|
||||||
else if (res.status===500)
|
|
||||||
alert('Backend failed! Please try again. If the problem persists, please email hostmaster@[this domain].')
|
|
||||||
else alert('Unknown error! Please try again. If the problem persists, please email hostmaster@[this domain].')
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
console.log(res.json())
|
||||||
|
send.disabled = false
|
||||||
|
|
||||||
|
if (res.status===200) {
|
||||||
|
text.value = ''; subj.value = ''; name.value = ''; email.value = ''
|
||||||
|
alert(Sent!')
|
||||||
|
} else if (res.status===500)
|
||||||
|
alert('Backend failed! Please try again. If the problem persists, please email hostmaster@[this domain].')
|
||||||
|
else alert('Unknown error! Please try again. If the problem persists, please email hostmaster@[this domain].')
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
73
index.js
73
index.js
|
@ -1,69 +1,48 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const app = express()
|
const app = express()
|
||||||
const {verify} = require('hcaptcha')
|
|
||||||
const PORT = process.env.PORT || 8080
|
const PORT = process.env.PORT || 8080
|
||||||
|
|
||||||
const mailer = require('nodemailer').createTransport({
|
const mailer = require('nodemailer').createTransport({
|
||||||
host: process.env.MAIL_SERVER,
|
host: process.env.MAIL_SERVER,
|
||||||
port: 587,
|
port: (process.env.MAIL_USER!=null)?25:587,
|
||||||
auth: {
|
auth: (process.env.MAIL_USER!=null)?null:{
|
||||||
user: process.env.MAIL_USER,
|
user: process.env.MAIL_USER,
|
||||||
pass: process.env.MAIL_PASS,
|
pass: process.env.MAIL_PASS,
|
||||||
},
|
},
|
||||||
tls: {
|
tls: (process.env.MAIL_USER!=null)?null:{
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
app.use(express.json())
|
app.use(express.json()).post('/', async (req, res) => {
|
||||||
app.post('/', async (req, res) => {
|
|
||||||
// console.log(`Received token: ${req.body['token']}`)
|
// Parse from address
|
||||||
|
let from
|
||||||
// Check token
|
if (req.body['name'] && req.body['email']) from = `${req.body['name']} <${req.body['email']}>`
|
||||||
let data
|
else if (req.body['name']) from = req.body['name']
|
||||||
|
else if (req.body['email']) from = req.body['email']
|
||||||
|
else from = 'Anonymous'
|
||||||
|
|
||||||
|
// Send email
|
||||||
|
let mail_res;
|
||||||
try {
|
try {
|
||||||
data = await verify(process.env.HCAPTCHA_SECRET, req.body['token'])
|
console.log(`Sending email from ${from} to ${process.env.MAIL_TO}...`)
|
||||||
|
mail_res = await mailer.sendMail({
|
||||||
|
from: process.env.MAIL_FROM,
|
||||||
|
replyTo: from,
|
||||||
|
to: process.env.MAIL_TO,
|
||||||
|
subject: req.body['subj'],
|
||||||
|
text: req.body['msg'],
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Failed to check hcaptcha\n${err}`)
|
console.error(err)
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
}
|
}
|
||||||
if (data.success === true) {
|
console.log(`Sent email ${mail_res.messageId}`)
|
||||||
|
return res.sendStatus(200)
|
||||||
|
|
||||||
// Parse from address
|
}).listen(PORT, () => {
|
||||||
let from
|
|
||||||
if (req.body['name'] && req.body['email']) from = `${req.body['name']} <${req.body['email']}>`
|
|
||||||
else if (req.body['name']) from = req.body['name']
|
|
||||||
else if (req.body['email']) from = req.body['email']
|
|
||||||
else from = 'Anonymous'
|
|
||||||
|
|
||||||
// Send email
|
|
||||||
let mail_res;
|
|
||||||
try {
|
|
||||||
console.log(`Sending email from ${from} to ${process.env.MAIL_TO}...`)
|
|
||||||
mail_res = await mailer.sendMail({
|
|
||||||
from: process.env.MAIL_FROM,
|
|
||||||
replyTo: from,
|
|
||||||
to: process.env.MAIL_TO,
|
|
||||||
subject: req.body['subj'],
|
|
||||||
text: req.body['msg'],
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
return res.sendStatus(500)
|
|
||||||
}
|
|
||||||
console.log(`Sent email ${mail_res.messageId}`)
|
|
||||||
return res.sendStatus(200)
|
|
||||||
|
|
||||||
// hcaptcha failed
|
|
||||||
} else {
|
|
||||||
console.log(`Failed hCaptcha with errors: ${data['error-codes']}`)
|
|
||||||
return res.sendStatus(403)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
|
||||||
console.log(`API listening on ${PORT}`)
|
console.log(`API listening on ${PORT}`)
|
||||||
})
|
})
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,10 +10,9 @@
|
||||||
"author": "Keith Irwin",
|
"author": "Keith Irwin",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.20.2",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.18.2",
|
||||||
"hcaptcha": "^0.1.0",
|
"nodemailer": "^6.9.1"
|
||||||
"nodemailer": "^6.7.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue