Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SMTP and discord webhooks for verification codes #72

Merged
merged 3 commits into from
Feb 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,28 @@ Table of contents
## Deployment Configuration Guide
(Example configuration with none-json notes)
```json
{
"verification": false, // disabled by default
"api_key":" Your sendgrid API key used to access your account from the API to send emails",
"sendFromEmail":"The email that will send the one time password (MUST BE VERIFIED IN SENDGRID)",
"type": "code", // DO NOT TOUCH
"email": " The email you want to use for recieving OTP "
{
"sendgrid_verification": false,
"sendgrid_options": {
"api_key": "YOUR_SENDGRID_API_KEY",
"sendFromEmail": "THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO"
},

"discord_verification": false,
"webhook_url": "YOUR DISCORD WEBHOOK URL",

"smtp_verification": false,
"smtp_options": {
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO",
"sendFromEmail": "THE EMAIL THE CODES ARE SENT FROM",
"host": "YOUR SMTP HOST",
"port": 465,
"auth": {
"user": "SMTP USER",
"pass": "YOUR PASSWORD"
}
}
}
```

Expand All @@ -69,8 +85,10 @@ Email verification is a new and unique feature that we've implemented in the eve
### What does it do
When a user tries to access the website, before allowed access they will be asked for a One time password sent to an email set in the deployment configuration. Once verified, they will have 15 day access to the site.

#### SendGrid Setup Instructions
* Firstly, We need to enable verification within the deployment configuration
* change `"verification":false,` to `"verification":true,`
* change `"sendgrid_verification":false,` to `"sendgrid_verification":true,` above the SendGrid Section

* _Note: You have to reboot the node app for any changes to take place._
* Now, we need to use an api to send a message
* Make an account at Sendgrid (https://app.sendgrid.com/)
Expand All @@ -79,7 +97,22 @@ When a user tries to access the website, before allowed access they will be aske
* Go to settings -> Sender authentication and click Verify a Single Sender
* Now, We need to get the API key to connect to the API
* Go to settings -> API Keys -> and make an API key.
* Complete the information in the deployment config `deployment.config.json` such as:
* Complete the information in the deployment config `deployment.config.json` under the `sendgrid_options` section such as: sendFromEmail, to_email and api_key

#### Discord Webhook Setup Instructions
* Set discord_verification to true in the deployment configuration.
* Create a channel in a discord server you have admin in.
* Click the Edit Channel button.
* Click Integrations
* Click create web hook and copy the URL.
* Paste it under the `webhook_url` section in the deployment configuration.

#### SMTP Setup Instructions
* Set `smtp_verification` to true.
* Change `to_email` to the email address you want the codes to be sent to.
* Change `sendFromEmail to the email address that is going to send the codes.
* Get the host and port from your email provider's documentation.
* Fill in your username and password under the `user` and `pass` section under auth.


## Advanced Deployment
Expand Down
210 changes: 118 additions & 92 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,149 +1,175 @@
import createBareServer from "@tomphttp/bare-server-node"
import http from "http"
import { fileURLToPath } from "url"
import { dirname, join } from "path"
import serveStatic from "serve-static"
import { createRequire } from "module"
const require = createRequire(import.meta.url)
const config = require("./deployment.config.json")
import fs from "fs"
var base64data
import sgTransport from "nodemailer-sendgrid-transport"
import nodemailer from "nodemailer"
import createBareServer from "@tomphttp/bare-server-node";
import http from "http";
import {createRequire} from "module";
import {dirname, join} from "path";
import serveStatic from "serve-static";
import {fileURLToPath} from "url";
const require = createRequire(import.meta.url);
const config = require("./deployment.config.json");
import fs from "fs";
var base64data;
import sgTransport from "nodemailer-sendgrid-transport";
import nodemailer from "nodemailer";
import fetch from "node-fetch";
const options = {
auth: {
api_key: config.api_key,
auth : {
api_key : config.sendgrid_options.api_key,
},
}
const mailerAgent = nodemailer.createTransport(sgTransport(options))
function sendVerificationEmail(UUID, mailTo, OTP) {
const email = {
to: mailTo,
from: `${config.sendFromEmail}`,
subject: `NebulaWEB personal access code ${OTP}`,
text: `
};
const sendgridMailerAgent = nodemailer.createTransport(sgTransport(options));
const smtpMailerAgent = nodemailer.createTransport(config.smtp_options);
function sendVerificationEmail(UUID, OTP) {
let email = {
to : "",
from : "",
subject : `NebulaWEB personal access code ${OTP}`,
text : `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)`,
html: `
html : `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)
`,
};
if (config.sendgrid_verification == true) {
email.to = config.sendgrid_options.to_email
email.from = config.sendgrid_options.sendFromEmail
sendgridMailerAgent.sendMail(email, (err, res) => {
if (err) {
console.log(err);
}
console.log(res);
});
}
if (config.verification == true) {
mailerAgent.sendMail(email, (err, res) => {
if (config.smtp_verification == true) {
email.to = config.smtp_options.to_email
email.from = config.smtp_options.sendFromEmail
smtpMailerAgent.sendMail(email, (err, res) => {
if (err) {
console.log(err)
console.log(err);
}
console.log(res)
})
console.log(res);
});
}
if (config.discord_verification == true) {
fetch(config.webhook_url, {
method : "POST",
headers : {
"Content-Type" : "application/json",
},
body : JSON.stringify({
content : `Your NebulaWEB access code is ${OTP}`,
}),
});
}
}

function getNewCode() {
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1)
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1);
if (seq == "0") {
getNewCode()
getNewCode();
}
return seq
return seq;
}

const PORT = process.env.PORT || 3000
const PORT = process.env.PORT || 3000;
const bareServer = createBareServer("/bare/", {
logErrors: false,
localAddress: undefined,
})
logErrors : false,
localAddress : undefined,
});

const serve = serveStatic(
join(dirname(fileURLToPath(import.meta.url)), "static/"),
{
fallthrough: false,
maxAge: 5 * 60 * 1000,
}
)
const serve =
serveStatic(join(dirname(fileURLToPath(import.meta.url)), "static/"), {
fallthrough : false,
maxAge : 5 * 60 * 1000,
});

const server = http.createServer()
const server = http.createServer();

server.on("request", (request, response) => {
try {
if (bareServer.shouldRoute(request)) {
bareServer.routeRequest(request, response)
bareServer.routeRequest(request, response);
} else {
let base64data
const url = request.url
let base64data;
const url = request.url;
if (url.startsWith("/sendNewCode")) {
const OTP = getNewCode()
fs.writeFile("./memory.txt", OTP, function (err) {
if (err) return console.log(err)
console.log(`Wrote OTP code to temp file`)
})
const OTP = getNewCode();
fs.writeFile("./memory.txt", OTP, function(err) {
if (err)
return console.log(err);
console.log(`Wrote OTP code to temp file`);
});

fs.readFile("./memory.txt", "utf8", (err, data) => {
if (err) {
console.error(err)
return
console.error(err);
return;
}
console.log(data)
console.log(data);

sendVerificationEmail("10", config.email, data)
let buff = new Buffer(data)
base64data = buff.toString("base64")
console.log("302")
sendVerificationEmail("10", data);
let buff = new Buffer(data);
base64data = buff.toString("base64");
console.log("302");
response.writeHead(302, {
location: "/unv.html?c=" + base64data,
})
response.end()
})
location : "/unv.html?c=" + base64data,
});
response.end();
});
} else if (url.startsWith("/verification")) {
var body
if (config.verification == true) {
const body = "true"
var body;
if (config.sendgrid_verification == true ||
config.discord_verification == true ||
config.smtp_verificaton == true) {
const body = "true";
response.writeHead(200, {
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain",
})
response.end(body)
"Content-Length" : Buffer.byteLength(body),
"Content-Type" : "text/plain",
});
response.end(body);
} else {
const body = "false"
const body = "false";
response.writeHead(200, {
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain",
})
response.end(body)
"Content-Length" : Buffer.byteLength(body),
"Content-Type" : "text/plain",
});
response.end(body);
}
} else {
serve(request, response, (err) => {
response.writeHead(err?.statusCode || 500, null, {
"Content-Type": "text/plain",
})
response.end(err?.stack)
})
"Content-Type" : "text/plain",
});
response.end(err?.stack);
});
}
}
} catch (e) {
response.writeHead(500, "Internal Server Error", {
"Content-Type": "text/plain",
})
response.end(e.stack)
"Content-Type" : "text/plain",
});
response.end(e.stack);
}
})
});
server.on("upgrade", (req, socket, head) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeUpgrade(req, socket, head)
bareServer.routeUpgrade(req, socket, head);
} else {
socket.end()
socket.end();
}
})
});

server.listen(PORT)
server.listen(PORT);

if (process.env.UNSAFE_CONTINUE)
process.on("uncaughtException", (err, origin) => {
console.error(`Critical error (${origin}):`)
console.error(err)
console.error("UNSAFELY CONTINUING EXECUTION")
console.error()
})
console.error(`Critical error (${origin}):`);
console.error(err);
console.error("UNSAFELY CONTINUING EXECUTION");
console.error();
});

console.log(`Server running at http://localhost:${PORT}/.`)
console.log(`Server running at http://localhost:${PORT}/.`);
30 changes: 23 additions & 7 deletions deployment.config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
{
"verification": false,
"api_key":"YOUR_SENDGRID_API_KEY",
"sendFromEmail":"THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"type": "code",
"email": "YOUR_EMAIL_HERE"
}
{
"sendgrid_verification": false,
"sendgrid_options": {
"api_key": "YOUR_SENDGRID_API_KEY",
"sendFromEmail": "THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO"
},

"discord_verification": false,
"webhook_url": "YOUR DISCORD WEBHOOK URL",

"smtp_verification": false,
"smtp_options": {
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO",
"sendFromEmail": "THE EMAIL THE CODES ARE SENT FROM",
"host": "YOUR SMTP HOST",
"port": 465,
"auth": {
"user": "SMTP USER",
"pass": "YOUR PASSWORD"
}
}
}
Loading