added suggestion box
This commit is contained in:
parent
7c4f634eed
commit
b09f894ffe
@ -1,3 +1,9 @@
|
|||||||
SESSION_SECRET=
|
SESSION_SECRET=
|
||||||
MONGODB_CONN="mongodb://127.0.0.1:27017/howfeed"
|
MONGODB_CONN="mongodb://127.0.0.1:27017/howfeed"
|
||||||
SALT_WORK_FACTOR=10
|
SALT_WORK_FACTOR=10
|
||||||
|
|
||||||
|
SMTP_SERVER=
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USERNAME=
|
||||||
|
SMTP_PASSWORD=
|
||||||
|
SMTP_RECIPIENTS="a@example.com, b@example.com"
|
||||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -4896,6 +4896,11 @@
|
|||||||
"integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==",
|
"integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nodemailer": {
|
||||||
|
"version": "6.4.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.11.tgz",
|
||||||
|
"integrity": "sha512-BVZBDi+aJV4O38rxsUh164Dk1NCqgh6Cm0rQSb9SK/DHGll/DrCMnycVDD7msJgZCnmVa8ASo8EZzR7jsgTukQ=="
|
||||||
|
},
|
||||||
"nopt": {
|
"nopt": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"helmet": "^3.23.3",
|
"helmet": "^3.23.3",
|
||||||
"mongoose": "^5.10.2",
|
"mongoose": "^5.10.2",
|
||||||
"mongoose-fuzzy-searching": "^1.3.1",
|
"mongoose-fuzzy-searching": "^1.3.1",
|
||||||
|
"nodemailer": "^6.4.11",
|
||||||
"passport": "^0.4.1",
|
"passport": "^0.4.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"rate-limiter-flexible": "^2.1.10",
|
"rate-limiter-flexible": "^2.1.10",
|
||||||
|
@ -2,6 +2,33 @@
|
|||||||
<title>Contact Us | HOWFEED.BIZ</title>
|
<title>Contact Us | HOWFEED.BIZ</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let title = '', name = '', message = '';
|
||||||
|
|
||||||
|
async function sendSuggestion()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/suggestions`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ title, name, message })
|
||||||
|
});
|
||||||
|
const json = await res.json();
|
||||||
|
if (res.status === 200) {
|
||||||
|
alert(json.message);
|
||||||
|
title = name = message = '';
|
||||||
|
} else {
|
||||||
|
alert(`Error ${res.status}: ${json.message}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div.people {
|
div.people {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -9,11 +36,20 @@
|
|||||||
}
|
}
|
||||||
div.people > div {
|
div.people > div {
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
padding: 1rem;
|
padding: 0.25rem 1rem;
|
||||||
}
|
}
|
||||||
iframe {
|
iframe {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
input[type=text], textarea {
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
height: 160px;
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -46,7 +82,16 @@
|
|||||||
<p><a href="mailto:webmaster@howfeed.biz">webmaster@howfeed.biz</a></p>
|
<p><a href="mailto:webmaster@howfeed.biz">webmaster@howfeed.biz</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<h1>Suggest Ideas to Us</h1>
|
||||||
|
<p>Do you have a request for an article or an enhancement to the site? Send it directly to us here!</p>
|
||||||
|
<form on:submit|preventDefault={sendSuggestion} action="/suggestions" method="POST">
|
||||||
|
<p>Name: <input type="text" name="name" bind:value={name} placeholder="Anonymous"></p>
|
||||||
|
<p>Title: <input type="text" name="title" bind:value={title}></p>
|
||||||
|
<p><textarea name="message" bind:value={message}></textarea></p>
|
||||||
|
<p><button type="submit">Send</button></p>
|
||||||
|
</form>
|
||||||
<!-- ad goes here -->
|
<!-- ad goes here -->
|
||||||
|
<h1 class="center">Come Find Us!</h1>
|
||||||
<div style="max-width:100%;margin:0 auto;width:700px;height:440px;">
|
<div style="max-width:100%;margin:0 auto;width:700px;height:440px;">
|
||||||
<iframe width="700" height="440" src="https://maps.google.com/maps?width=700&height=440&hl=en&q=1198%20Sixth%20St%2C%20San%20Jose%2C%20CA+(Title)&ie=UTF8&t=&z=14&iwloc=B&output=embed" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
|
<iframe width="700" height="440" src="https://maps.google.com/maps?width=700&height=440&hl=en&q=1198%20Sixth%20St%2C%20San%20Jose%2C%20CA+(Title)&ie=UTF8&t=&z=14&iwloc=B&output=embed" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,7 @@ import { Strategy } from 'passport-local';
|
|||||||
import sessionFileStore from 'session-file-store';
|
import sessionFileStore from 'session-file-store';
|
||||||
import { RateLimiterMemory } from 'rate-limiter-flexible';
|
import { RateLimiterMemory } from 'rate-limiter-flexible';
|
||||||
import fileUpload from 'express-fileupload';
|
import fileUpload from 'express-fileupload';
|
||||||
|
import nodemailer from 'nodemailer';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
@ -25,7 +26,8 @@ import legacyRouter from './legacy/router.js';
|
|||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const FileStore = sessionFileStore(session);
|
const FileStore = sessionFileStore(session);
|
||||||
|
|
||||||
const { PORT, NODE_ENV, SESSION_SECRET, MONGODB_CONN } = process.env;
|
const { PORT, NODE_ENV, SESSION_SECRET, MONGODB_CONN,
|
||||||
|
SMTP_USERNAME, SMTP_PASSWORD, SMTP_SERVER, SMTP_PORT, SMTP_RECIPIENTS } = process.env;
|
||||||
const dev = NODE_ENV === 'development';
|
const dev = NODE_ENV === 'development';
|
||||||
|
|
||||||
mongoose.set('useNewUrlParser', true);
|
mongoose.set('useNewUrlParser', true);
|
||||||
@ -111,6 +113,16 @@ const isAuthor = function(req, res, next) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mailer = nodemailer.createTransport({
|
||||||
|
host: SMTP_SERVER,
|
||||||
|
port: 587,
|
||||||
|
secure: SMTP_PORT === 465,
|
||||||
|
auth: {
|
||||||
|
user: SMTP_USERNAME,
|
||||||
|
pass: SMTP_PASSWORD
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
@ -429,7 +441,44 @@ mainRouter
|
|||||||
'Content-Type': 'application/rss+xml'
|
'Content-Type': 'application/rss+xml'
|
||||||
});
|
});
|
||||||
res.end(feed.xml());
|
res.end(feed.xml());
|
||||||
});
|
})
|
||||||
|
.post('/suggestions', async function (req, res) {
|
||||||
|
let { name, title, message } = req.body;
|
||||||
|
if (!message) {
|
||||||
|
res.writeHead(422, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
message: 'No message supplied'
|
||||||
|
}));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
name = name || 'Anonymous';
|
||||||
|
title = title || 'Suggestion';
|
||||||
|
try {
|
||||||
|
await mailer.sendMail({
|
||||||
|
from: `"HowFeed Suggestions" <${SMTP_USERNAME}>`,
|
||||||
|
to: SMTP_RECIPIENTS,
|
||||||
|
subject: title,
|
||||||
|
text: `Suggested by ${name}:
|
||||||
|
|
||||||
|
${message}`
|
||||||
|
});
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
message: 'Your suggestion was delivered.'
|
||||||
|
}));
|
||||||
|
} catch (err) {
|
||||||
|
res.writeHead(500, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
message: err.message
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.use(helmet())
|
app.use(helmet())
|
||||||
.use(cors())
|
.use(cors())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user