Added documentation and clientside code
parent
e6eb24b525
commit
266232dceb
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright © 2021 Keith Irwin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,62 @@
|
||||||
|
# mailapi
|
||||||
|
|
||||||
|
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
|
||||||
|
- An API which checks the captcha and sends the message by email
|
||||||
|
|
||||||
|
## Setting up a server
|
||||||
|
|
||||||
|
Download the source; it's not on docker hub.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://gitea.gf4.pw/ki9/mailapi.git
|
||||||
|
cd mailapi
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the sample environment files and edit them to suit your needs.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp .env.sample .env
|
||||||
|
cp docker-compose.yml.sample docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the service with docker:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
...*or* start the service directly, or with a daemon manager:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
|
||||||
|
The API should now be listening on port 8080 or whatever you set in the `docker-compose.yml`. You may choose to run this through a proxy server or whatever.
|
||||||
|
|
||||||
|
## Serving the clientside app
|
||||||
|
|
||||||
|
You can use the contact form in `index.html.sample`. Tweak it to your needs and put it in your clientside code. I'm not offering support for your particular set up, but the code in both `index.html.sample` and `index.js` is short and easy to modify to your use case.
|
||||||
|
|
||||||
|
## MIT License
|
||||||
|
|
||||||
|
Copyright © 2021 Keith Irwin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,77 @@
|
||||||
|
<p>You may use this web form to contact us. Your message will be encrypted. A copy of your message will not be sent to you unless we reply. For an encrypted reply, paste or link your public key. </p>
|
||||||
|
|
||||||
|
<noscript><p>Uh-oh, you don't have javascript. This form won't work without it. Please send an email instead.</p></noscript>
|
||||||
|
|
||||||
|
<p><input type="text" id="name-input" placeholder="Your name"></p>
|
||||||
|
<p><input type="email" id="email-input" placeholder="Your email"></p>
|
||||||
|
<p><input type="text" id="subject-input" placeholder="Subject"></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 id="msg"></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>/* global openpgp fetch */
|
||||||
|
let msg = document.getElementById('msg')
|
||||||
|
let send = document.getElementById('send-button')
|
||||||
|
let name = document.getElementById('name-input')
|
||||||
|
let email = document.getElementById('email-input')
|
||||||
|
let subj = document.getElementById('subject-input')
|
||||||
|
let text = document.getElementById('message-input')
|
||||||
|
|
||||||
|
const API_URL = "https://mailapi.mydomain.tld/"
|
||||||
|
|
||||||
|
async function sendClicked (captchaToken) {
|
||||||
|
if (captchaToken) {
|
||||||
|
send.disabled = true
|
||||||
|
msg.innerHTML = `Sending... `
|
||||||
|
let res; try {
|
||||||
|
res = await fetch(API_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
// cache: 'no-cache',
|
||||||
|
headers: {'content-type': 'application/json'},
|
||||||
|
body: JSON.stringify({
|
||||||
|
token: captchaToken,
|
||||||
|
name: name.value,
|
||||||
|
subj: subj.value,
|
||||||
|
email: email.value,
|
||||||
|
msg: await openpgp.encrypt({
|
||||||
|
message: await openpgp.createMessage(
|
||||||
|
{ text: `${text.value}\n` }
|
||||||
|
),
|
||||||
|
encryptionKeys: await openpgp.readKey({
|
||||||
|
armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQGNBF/TtIoBDADvYLnftyJjfWoeK0zE3Yh3jYsuAj27aU039xh6VaX0IsXQqKLD
|
||||||
|
...
|
||||||
|
lk6lY0ktTb+vRnndyN3m+XW1mYdv3xUZMjQwMBtgdZbfY43pq8+N55tSTycF
|
||||||
|
=Wvbt
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----`,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
send.disabled = false
|
||||||
|
console.error(err)
|
||||||
|
msg.innerHTML = `Failed to connect to the network. Are you online?`
|
||||||
|
}
|
||||||
|
console.log(res.json())
|
||||||
|
send.disabled = false
|
||||||
|
|
||||||
|
if (res.status===200) {
|
||||||
|
text.value = ''; subj.value = ''; name.value = ''; email.value = ''
|
||||||
|
msg.innerHTML = `Sent!`
|
||||||
|
} else if (res.status===403)
|
||||||
|
msg.innerHTML = `hCaptcha failed! Please try again.`
|
||||||
|
else if (res.status===500)
|
||||||
|
msg.innerHTML = `Backend failed! Please try again. If the problem persists, please email hostmaster@[this domain].`
|
||||||
|
else msg.innerHTML = `Unknown error! Please try again. If the problem persists, please email hostmaster@[this domain].`
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue