adding Admin server

This commit is contained in:
Luke Berndt
2021-01-10 22:23:09 -05:00
parent c8b4f02d06
commit 86eb854848
156 changed files with 53167 additions and 15978 deletions

View File

@@ -0,0 +1,60 @@
const path = require("path");
const express = require("express");
const session = require("express-session");
const bodyParser = require("body-parser");
const connectMongo = require("connect-mongo");
const secrets = require("./secrets");
const MongoStore = connectMongo(session)
var cookie_domain = process.env['COOKIE_DOMAIN'] != null ? process.env['COOKIE_DOMAIN'] : '.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
module.exports = function(app, passport) {
app.set("port", 3009)
// X-Powered-By header has no functional value.
// Keeping it makes it easier for an attacker to build the site's profile
// It can be removed safely
app.disable("x-powered-by")
app.enable('trust proxy')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(express.static(path.join(process.cwd(), 'public')));
const sess = {
secret: 'secret',
/*saveUninitialized: false,
resave: false,*/
resave: true,
saveUninitialized: true,
secret: secrets.sessionSecret,
proxy: true,
name: "sessionId",
cookie: {
httpOnly: true,
secure: false,
domain: cookie_domain
},
store: new MongoStore({
url: secrets.db,
autoReconnect: true
})
}
var node_env = process.env.NODE_ENV;
console.log('--------------------------');
console.log('===> 😊 Starting Server . . .');
console.log('===> Environment: ' + node_env);
/*if(node_env === 'production') {
console.log('===> 🚦 Note: In order for authentication to work in production');
console.log('===> you will need a secure HTTPS connection');
sess.cookie.secure = true; // Serve secure cookies
sess.cookie.httpOnly = false;
}*/
app.use(session(sess))
app.use(passport.initialize())
app.use(passport.session())
}

View File

@@ -0,0 +1,34 @@
/*
Configuring local strategy to authenticate strategies
Code modified from : https://github.com/madhums/node-express-mongoose-demo/blob/master/config/passport/local.js
*/
const LocalStrategy = require("passport-local").Strategy;
const User = require("../../models/user");
/*
By default, LocalStrategy expects to find credentials in parameters named username and password.
If your site prefers to name these fields differently, options are available to change the defaults.
*/
const local = new LocalStrategy({
usernameField: "email"
}, (email, password, done) => {
User.findOne({
$or: [{
email
}, {
local: {
email
}
}]
}, (err, user) => {
if(!user) return done(null, false, { message: `Email ${email} not found` })
user.comparePassword(password, (err, isMatch) => {
if (isMatch) {
return done(null, user)
} else {
return done(null, false, { message: "Invalid email or password" })
}
})
})
})
module.exports = local;

View File

@@ -0,0 +1,26 @@
/* Initializing PassportJS */
const User = require("../models/user");
const local = require("./passport-strategies/local");
module.exports = function (app, passport) {
// Configure Passport authenticated session persistence.
//
// In order to restore authentication state across HTTP requests, Passport needs
// to serialize users into and deserialize users out of the session. The
// typical implementation of this is as simple as supplying the user ID when
// serializing, and querying the user record by ID from the database when
// deserializing.
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user)
})
})
// use the following strategies
passport.use(local)
}

View File

@@ -0,0 +1,15 @@
/** Important **/
/** You should not be committing this file to GitHub **/
/** Repeat: DO! NOT! COMMIT! THIS! FILE! TO! YOUR! REPO! **/
var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : 27017;
var mongoUrl = 'mongodb://' + host + ':' + port + '/scanner';
const secrets = {
db: mongoUrl,
sessionSecret: "letthisbeyoursecret"
}
module.exports = secrets

View File

@@ -0,0 +1,272 @@
const mongoose = require("mongoose");
const Plan = require("../models/plan");
const System = require("../models/system");
const stripeKeyPublishable = process.env.STRIPE_PUBLISHABLE_KEY;
const stripeKeySecret = process.env.STRIPE_SECRET_KEY;
const stripe = require("stripe")(stripeKeySecret);
var admin_email = process.env['ADMIN_EMAIL'] != null ? process.env['ADMIN_EMAIL'] : "luke@openmhz.com";
var site_name = process.env['SITE_NAME'] != null ? process.env['SITE_NAME'] : "OpenMHz";
var account_server = process.env['ACCOUNT_SERVER'] != null ? process.env['ACCOUNT_SERVER'] : "https://account.openmhz.com";
var cookie_domain = process.env['COOKIE_DOMAIN'] != null ? process.env['COOKIE_DOMAIN'] : '.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
exports.isLoggedIn = function (req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect("/login");
};
function makeSystemsResponse(systems) {
var returnSys = systems.map(obj => {
var rObj = (({
name,
shortName,
description,
systemType,
city,
state,
county,
country,
userId,
key,
planType,
showScreenName
}) => ({
name,
shortName,
description,
systemType,
city,
state,
county,
country,
userId,
key,
planType,
showScreenName
}))(obj);
rObj.id = obj._id;
return rObj;
});
return returnSys;
}
function findSubscriptionItem(subscription, planId) {
var items = subscription.items.data;
var subscriptionItem = items.find(function (element) {
return element.plan.id == planId;
});
return subscriptionItem;
};
// -------------------------------------------
// makes sure the plans a user is trying to update actually belong to them.
function validatePlans(systems, updatedPlans) {
var validatedPlans = [];
systems.forEach(function (system) {
// Find the updated plan for that system.
const updatedPlan = updatedPlans.find(function (element) {
return element.shortName == system.shortName;
})
if (!updatedPlan) {
console.log("ERROR: updated plan not found for ShortName");
}
// Update that systems plan type
// TODO: add validation of plantype
system.planType = updatedPlan.planType;
validatedPlans.push({ shortName: system.shortName, planType: updatedPlan.planType });
});
return validatedPlans;
}
exports.updatePlans = async function (req, res, next) {
const userId = mongoose.Types.ObjectId(req.user._id);
if (!req.user.customerId) {
console.log("ERROR: user does not have billing setup");
res.json({
success: false,
message: "ERROR: user does not have billing setup"
});
return;
}
const updatedPlans = req.body.updatePlans;
console.log(updatedPlans);
try {
var plan = await Plan.findOne({ userId: userId });
// looks like the User does not have a plan yet
if (!plan) {
plan = new Plan({ userId: userId });
}
// Find all of the Users Systems
var systems = await System.find({ userId: mongoose.Types.ObjectId(req.user._id) })
} catch (err) {
console.log("Error upate plans: " + err);
res.json({
success: false,
message: err
});
return;
}
// For each of the User's Systems
var validatedPlans = validatePlans(systems, updatedPlans);
// Create the subscription object
console.log("---------Validated Plans--------");
console.log(validatedPlans);
var proPlans = { plan: "plan_EQoJeqkAw6FCgy", quantity: 0 };
var proPlanSystems = [];
var proPlanQuantity = 0;
validatedPlans.forEach(function (plan) {
if (plan.planType == 10) {
proPlanQuantity++;
proPlans.quantity++;
proPlanSystems.push(plan.shortName);
}
});
if (!plan.subscriptionId) {
//proPlans.metadata = proPlanSystems.join();
var items = [];
items.push(proPlans);
//Subscribe the User
console.log(subscription);
try {
var subscription = await stripe.subscriptions.create({
customer: req.user.customerId,
items: items
});
console.log(subscription);
const subscriptionItem = findSubscriptionItem(subscription, "plan_EQoJeqkAw6FCgy");
if (subscriptionItem) {
plan.proSystemSubscription = { subscriptionItemId: subscriptionItem.id, quantity: proPlanQuantity, systems: proPlanSystems };
plan.subscriptionId = subscription.id;
await plan.save();
systems.forEach(async function (system) { await system.save(); });
// Save the updated Systems
const returnSystems = makeSystemsResponse(systems);
res.json({
success: true,
systems: returnSystems
});
return;
}
} catch (err) {
console.log("Error upate plans: " + err);
res.json({
success: false,
message: err
});
return;
}
} else {
// we alreay have a Subscription for the User
try {
var subscriptionItem=null;
// Check if the user has a Pro Plan subscription Item setup yet.
if (plan.proSystemSubscription) {
subscriptionItem = await stripe.subscriptionItems.update(plan.proSystemSubscription.subscriptionItemId,
{
quantity: proPlanQuantity,
});
} else {
// Create one if they don't
subscriptionItem = await stripe.subscriptionItems.create(
{
subscription: plan.subscriptionId,
plan: "plan_EQoJeqkAw6FCgy",
quantity: proPlanQuantity,
});
}
if (subscriptionItem) {
plan.proSystemSubscription = { subscriptionItemId: subscriptionItem.id, quantity: proPlanQuantity, systems: proPlanSystems };
await plan.save();
systems.forEach(async function (system) { await system.save(); });
// Save the updated Systems
const returnSystems = makeSystemsResponse(systems);
res.json({
success: true,
systems: returnSystems
});
return;
}
} catch (err) {
console.log("Error upate plans: " + err);
res.json({
success: false,
message: err
});
return;
}
}
}
exports.getInvoices = async function (req, res, next) {
if (!req.user.customerId) {
console.log("ERROR: user does not have billing setup");
res.json({
success: false,
message: "ERROR: user does not have billing setup"
});
return;
}
try {
console.log("Trying to fetch invoices for: " + req.user.customerId);
var invoices = await stripe.invoices.list( { limit: 12, customer: req.user.customerId });
console.log(invoices);
var obj = invoices.data.map(obj => {
var rObj = (({
amount_due,
amount_paid,
date,
invoice_pdf,
paid,
status,
description
}) => ({
amount_due,
amount_paid,
date,
invoice_pdf,
paid,
status,
description
}))(obj);
rObj.id = obj._id;
return rObj;
});
return res.json({
success: true,
invoices: obj
});
} catch (err) {
console.log("Error retrieving licesnes: " + err);
res.json({
success: false,
message: err
});
return;
}
}

View File

@@ -0,0 +1,62 @@
const mongoose = require("mongoose");
const System = require("../models/system");
// -------------------------------------------
exports.getUserSystems = function(_id) {
console.log("Listing Systems for: " + _id);
System.find(
{
userId: mongoose.Types.ObjectId(_id)
},
function(err, systems) {
if (err) {
console.error("Error - ListSystems: " + err);
return({ success: false, message: err });
}
var returnSys = systems.map(obj => {
var rObj = (({
name,
shortName,
description,
systemType,
city,
state,
county,
country,
userId,
key,
planType,
showScreenName
}) => ({
name,
shortName,
description,
systemType,
city,
state,
county,
country,
userId,
key,
planType,
showScreenName
}))(obj);
rObj.id = obj._id;
return rObj;
});
return({ success: true, systems: returnSys });
}
);
}
exports.listSystems = function(req, res, next) {
return listSystems(req.user._id);
}

View File

@@ -0,0 +1,605 @@
const passport = require("passport");
const User = require("../models/user");
const mailjet = require("node-mailjet").connect(
process.env['MAILJET_KEY'],
process.env['MAILJET_SECRET']
);
const crypto = require("crypto");
var admin_email = process.env['ADMIN_EMAIL'] != null ? process.env['ADMIN_EMAIL'] : "luke@openmhz.com";
var site_name = process.env['SITE_NAME'] != null ? process.env['SITE_NAME'] : "OpenMHz";
var account_server = process.env['ACCOUNT_SERVER'] != null ? process.env['ACCOUNT_SERVER'] : "https://account.openmhz.com";
var cookie_domain = process.env['COOKIE_DOMAIN'] != null ? process.env['COOKIE_DOMAIN'] : '.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
exports.isLoggedIn = function(req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect("/login");
};
// -------------------------------------------
exports.authenticated = function(req, res, next) {
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
console.log("auth: " + req.isAuthenticated());
console.log("req.user: " + req.user);
if (req.isAuthenticated()) {
var clientUser = (({
firstName,
lastName,
screenName,
location,
email,
admin
}) => ({
firstName,
lastName,
screenName,
location,
email,
admin
}))(
req.user
);
clientUser.userId = req.user.id
if (req.user.customerId) {
clientUser.billing = true;
} else {
clientUser.billing = false;
}
return res.json({
success: true,
user: clientUser
});
} else {
return res.json({
success: false
});
}
}
exports.login = function(req, res, next) {
// Do email and password validation for the server
passport.authenticate("local", function(err, user, info) {
if (err) return next(err);
if (!user) {
return res.json({
success: false,
message: info.message
});
}
// ***********************************************************************
// "Note that when using a custom callback, it becomes the application's
// responsibility to establish a session (by calling req.login()) and send
// a response."
// Source: http://passportjs.org/docs
// ***********************************************************************
// Passport exposes a login() function on req (also aliased as logIn())
// that can be used to establish a login session
req.login(user, loginErr => {
if (loginErr) {
return res.json({
success: false,
message: loginErr
});
}
if (!user.confirmEmail) {
req.logout();
return res.json({
success: false,
message: "unconfirmed email",
userId: user.id
});
}
console.log(user);
// go ahead and create the new user
var clientUser = (({
firstName,
lastName,
screenName,
location,
email,
admin
}) => ({
firstName,
lastName,
screenName,
location,
email,
admin
}))(
user
);
clientUser.userId = user.id
return res.json({
success: true,
message: "authentication succeeded",
user: clientUser,
userId: user.id
});
});
})(req, res, next);
};
exports.confirmEmail = function(req, res, next) {
const userId = req.params["userId"];
const token = req.params["token"];
User.findById(userId, (err, user) => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
if (user.confirmEmail) {
console.log("User already confirmed email: " + userId);
res.json({
success: false,
message: "already confirmed email"
});
return;
}
const today = new Date();
if (user.confirmEmailTTL < today) {
res.json({
success: false,
message: "token expired"
});
return;
}
if (user.confirmEmailToken != token) {
console.log(
"Token Mismatch DB: " + user.confirmEmailToken + " submitted: " + token
);
res.json({
success: false,
message: "token mismatch"
});
return;
}
user.confirmEmail = true;
user.confirmEmailToken = "";
user.save(err => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
console.log("User: " + user.email + " confirmed email address");
res.json({
success: true
});
return;
});
});
};
exports.resetPassword = function(req, res, next) {
const userId = req.params["userId"];
const token = req.params["token"];
User.findById(userId, (err, user) => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
const today = new Date();
if (user.resetPasswordTTL < today) {
res.json({
success: false,
message: "token expired"
});
return;
}
if (user.resetPasswordToken != token) {
console.log(
"Token Mismatch DB: " + user.resetPasswordToken + " submitted: " + token
);
res.json({
success: false,
message: "token mismatch"
});
return;
}
user.password = req.body.password
user.confirmEmail = true;
user.confirmEmailToken = "";
user.resetPasswordToken = "";
user.save(err => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
res.json({
success: true
});
return;
});
});
};
// -------------------------------------------
exports.sendResetPassword = function(req, res, next) {
User.findOne({
email: req.body.email
}, (err, user) => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
if (!user) {
console.error("Reset password failed. No user: " + req.body.email);
res.json({
success: false,
message: "No account register for " + req.body.email
});
return;
}
const buffer = crypto.randomBytes(20);
const token = buffer.toString("hex");
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
user.resetPasswordToken = token;
user.resetPasswordTTL = tomorrow;
user.save(err => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
const request = mailjet.post("send", {
version: "v3.1"
}).request({
Messages: [{
From: {
Email: admin_email,
Name: site_name + " Admin"
},
To: [{
Email: user.email,
Name: user.firstName + " " + user.lastName
}],
Subject: site_name + " - Password Reset",
TextPart: "It looks like you may have forgot your password. Copy this link to your browser to reset your password. Let us know if you are receiving this but did not request a password reset. /r" + account_server + "/reset-password/" + user.id + "/" + token,
HTMLPart: "<h3>Thanks for using " + site_name + "!</h3><br />It looks like you may have forgot your password. Copy this link to your browser to reset your password. Let us know if you are receiving this but did not request a password reset.<p>" + account_server + "/reset-password/" + user.id + "/" + token + "</p>"
}]
});
request
.then(result => {
console.log(`Password reset sent to: ${user.email}`)
})
.catch(err => {
console.error(err.statusCode);
console.error(err);
res.json({
success: false,
message: err
});
return;
});
res.json({
success: true
});
return;
});
});
};
function handleSendConfirmEmail(user) {
return new Promise((resolve, reject) => {
if (user.confirmEmail) {
console.log("Error - Send Confirm Email - User already confirmed email: " + user.email);
reject({
success: false,
message: "already confirmed email"
});
return;
}
const buffer = crypto.randomBytes(20);
const token = buffer.toString("hex");
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
user.confirmEmailToken = token;
user.confirmEmailTTL = tomorrow;
user.save().then(function(user) {
return mailjet.post("send", {
version: "v3.1"
}).request({
Messages: [{
From: {
Email: admin_email,
Name: site_name + " Admin"
},
To: [{
Email: user.email,
Name: user.firstName + " " + user.lastName
}],
Subject: "Confirm " + site_name + " Account",
TextPart: "Thanks for signing up for " + site_name + ". We just wanted to check and make sure your email address was real. Copy and paste this addres in your browser to confirm your email address: " + account_server + "/confirm-email/" + user._id + "/" + token,
HTMLPart: "<h3>Thanks for signing up for " + site_name + "</h3><br />We just wanted to check and make sure your email address was real. Copy and paste this addres in your browser to confirm your email address:<p> " + account_server + "/confirm-email/" + user._id + "/" + token + "</p>"
}]
});
}).then(result => {
console.log("Confirm email sent to: " + user.email);
resolve({
success: true,
userId: user._id
});
}).catch(err => {
console.error("Admin Email: " + admin_email + " User Email: " + user.email);
console.error("Error - Send Confirm Email - caught: " + err);
reject({
success: false,
message: err
});
});
});
};
// -------------------------------------------
exports.sendConfirmEmail = function(req, res, next) {
const userId = req.params["userId"];
User.findById(userId, (err, user) => {
if (err) {
console.error("Error - Send Confirm Email: " + err);
res.json({
success: false,
message: err
});
return;
}
if (!user) {
console.error("Error - Send Confirm Email: User not found " + userId);
res.json({
success: false,
message: "user not found"
});
return;
}
handleSendConfirmEmail(user).then(function(result) {
res.json(result);
return;
}).catch(function(error) {
res.json(error);
return;
});
});
};
// -------------------------------------------
exports.logout = function(req, res, next) {
// the logout method is added to the request object automatically by Passport
req.logout();
res.clearCookie('sessionId', {domain: cookie_domain, path:'/'});
return res.json({
success: true
});
};
exports.terms = function(req, res, next) {
const userId = req.params["userId"];
User.findById(userId, (err, user) => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
if (req.user.id != userId) {
console.log(
"Logged in user's ID: " +
req.user.id +
" does not match Param: " +
userId
);
res.json({
success: false,
message: "UserID incorrect"
});
return;
}
user.terms = 1.1; //User.termsVer;
user.save(err => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
res.json({
success: true
});
return;
});
});
};
// -------------------------------------------
exports.validateProfile = function(req, res, next) {
if (!req.body.firstName || (req.body.firstName.length < 2)) {
console.error("ERROR: Validate System - req.body.firstName");
res.json({
success: false,
message: "First Name is Required"
});
return;
}
res.locals.firstName = req.body.firstName.replace(/[^\w\s\.\,\-\'\`]/gi, '');
if (!req.body.lastName || (req.body.lastName.length < 2)) {
console.error("ERROR: Validate System - req.body.lastName");
res.json({
success: false,
message: "Last Name is Required"
});
return;
}
res.locals.lastName = req.body.lastName.replace(/[^\w\s\.\,\-\'\`]/gi, '');
res.locals.screenName = req.body.screenName.replace(/[^\w\s\.\,\-\_]/gi, '');
if (!req.body.location || (req.body.location.length < 2)) {
console.error("ERROR: Validate System - req.body.location");
res.json({
success: false,
message: "System location is Required"
});
return;
}
res.locals.location = req.body.location.replace(/[^\w\s\.\,\-\_]/gi, '');
next();
}
exports.updateProfile = function(req, res, next) {
const userId = req.params["userId"];
User.findById(userId, (err, user) => {
// is email address already in use?
if (req.user.id != userId) {
console.log(
"ERROR: Logged in user's ID: " +
req.user.id +
" does not match Param: " +
userId
);
res.json({
success: false,
message: "UserID incorrect"
});
return;
}
// go ahead and create the new user
user.firstName = res.locals.firstName
user.lastName = res.locals.lastName
user.screenName = res.locals.screenName
user.location = res.locals.location
console.log(user)
user.save(err => {
if (err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
}
var clientUser = (({
firstName,
lastName,
screenName,
location
}) => ({
firstName,
lastName,
screenName,
location
}))(
user
);
console.log("Updated Profile: " + userId)
res.json({
success: true,
user: clientUser
});
return;
});
});
};
// -------------------------------------------
exports.register = function(req, res, next) {
User.findOne({
$or: [{
email: req.body.email
}, {
local: {
email: req.body.email
}
}]
}, (err, user) => {
// is email address already in use?
if (user) {
res.json({
success: false,
message: "Email already in use"
});
return;
}
// go ahead and create the new user
var user = (({
firstName,
lastName,
screenName,
location,
email,
password
}) => ({
firstName,
lastName,
screenName,
location,
}))(
res.locals
);
user.password = req.body.password;
user.email = req.body.email;
User.create(user).then(function(dbUser) {
console.log(dbUser);
// Since regiestration worked, send a confirmation email.
return handleSendConfirmEmail(dbUser);
}).then(function(result) {
res.json(result);
return;
}).catch(function(err) {
console.error(err);
res.json({
success: false,
message: err
});
return;
});
});
};

95
account/server/index.js Normal file
View File

@@ -0,0 +1,95 @@
const fs = require("fs");
const express = require("express");
const mongoose = require("mongoose");
const passport = require("passport");
const path = require("path");
const secrets = require("./config/secrets");
const configurePassport = require("./config/passport");
const configureExpress = require("./config/express");
const users = require("./controllers/users");
require("./models/user");
// -------------------------------------------
const app = express()
// -------------------------------------------
const connect = () => {
mongoose.connect(secrets.db, (err, res) => {
if (err) {
console.log(`Error connecting to ${secrets.db}. ${err}`)
} else {
console.log(`Successfully connected to ${secrets.db}.`)
}
})
}
connect()
mongoose.connection.on("error", console.error)
mongoose.connection.on("disconnected", connect)
// -------------------------------------------
const isDev = process.env.NODE_ENV === "development"
var backend_server = process.env['BACKEND_SERVER'] != null ? process.env['BACKEND_SERVER'] : 'https://api.openmhz.com';
var frontend_server = process.env['FRONTEND_SERVER'] != null ? process.env['FRONTEND_SERVER'] : 'https://openmhz.com';
var media_server = process.env['MEDIA_SERVER'] != null ? process.env['MEDIA_SERVER'] : 'https://media.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
var socket_server = process.env['SOCKET_SERVER'] != null ? process.env['SOCKET_SERVER'] : 'wss://api.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
var admin_server = process.env['ADMIN_SERVER'] != null ? process.env['ADMIN_SERVER'] : 'https://admin.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
var account_server = process.env['ACCOUNT_SERVER'] != null ? process.env['ACCOUNT_SERVER'] : 'https://account.openmhz.com'; //'https://s3.amazonaws.com/robotastic';
var site_name = process.env['SITE_NAME'] != null ? process.env['SITE_NAME'] : "OpenMHz";
const proPlanValue = process.env['PRO_PLAN'] != null ? process.env['PRO_PLAN'] : 10;
const freePlanValue = process.env['FREE_PLAN'] != null ? process.env['FREE_PLAN'] : 0;
const proPlanPrice = process.env['PRO_PLAN_PRICE'] != null ? process.env['PRO_PLAN_PRICE'] : 15;
const freePlanPrice = process.env['FREE_PLAN_PRICE'] != null ? process.env['FREE_PLAN_PRICE'] : 0;
// -------------------------------------------
configurePassport(app, passport)
configureExpress(app, passport)
app.all('*', function(req, res, next) {
var allowedOrigins = [account_server, admin_server, frontend_server];
var origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// -------------------------------------------
app.use(express.static(path.join(__dirname, "public")));
app.post("/login", users.login)
app.get("/logout", users.logout)
app.get("/authenticated", users.authenticated)
app.post("/register", users.validateProfile, users.register)
app.post("/users/:userId/reset-password/:token", users.resetPassword)
app.post("/api/send-reset-password", users.sendResetPassword)
app.post("/users/:userId", users.isLoggedIn, users.validateProfile, users.updateProfile)
app.post("/users/:userId/terms", users.isLoggedIn, users.terms)
app.post("/users/:userId/send-confirm", users.sendConfirmEmail)
app.post("/users/:userId/confirm/:token", users.confirmEmail)
app.get("*", (req, res, next) => {
res.sendFile('public/index.html');
});
// start listening to incoming requests
app.listen(app.get("port"), app.get("host"), (err) => {
if (err) {
console.err(err.stack)
} else {
console.log(`App listening on port ${app.get("port")} [${process.env.NODE_ENV} mode]`)
}
})

View File

@@ -0,0 +1,23 @@
// Defining a User Model in mongoose
// Code modified from https://github.com/sahat/hackathon-starter
const mongoose = require("mongoose");
var SubscriptionSchema = mongoose.Schema({ subscriptionItemId: String, quantity: {type: Number, default: 0}, systems: [String] });
const PlanSchema = new mongoose.Schema({
userId: mongoose.Schema.Types.ObjectId,
userPlan: {
type: Number,
default: 0
},
subscriptionId: String,
proSystemSubscription: SubscriptionSchema
})
module.exports = mongoose.model("Plan", PlanSchema)

View File

@@ -0,0 +1,27 @@
require('mongoose');
require('bcrypt-nodejs');
var systemSchema = mongoose.Schema({
name: String,
shortName: String,
systemType: String,
county: String,
country: String,
city: String,
state: String,
description: String,
showScreenName: Boolean,
planType: {type: Number, default: 0},
userId: mongoose.Schema.Types.ObjectId,
key: String
});
systemSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
systemSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('System', systemSchema);

View File

@@ -0,0 +1,92 @@
// Defining a User Model in mongoose
// Code modified from https://github.com/sahat/hackathon-starter
const bcrypt = require("bcrypt");
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
local: {
name: String,
email: String,
password: String
},
email: {
type: String,
unique: true,
lowercase: true
},
password: String,
screenName: {
type: String,
unique: true,
lowercase: true
},
firstName: String,
lastName: String,
location: String,
email: String,
resetPasswordToken: String,
resetPasswordTTL: Date,
confirmEmail: {
type: Boolean,
default: false
},
customerId: {
type: String,
default: ""
},
confirmEmailToken: String,
confirmEmailTTL: Date,
admin: {
type: Boolean,
default: false
},
terms: {
type: Number,
default: 0
},
ver: {
type: Number,
default: 1.1
},
sysCount: Number,
lastLogin: { type : Date, default: Date.now }
})
/**
* Password hash middleware.
*/
UserSchema.pre("save", function(next) {
var user = this
if (!user.isModified("password")) return next()
bcrypt.genSalt(8, (err, salt) => {
if (err) return next(err)
bcrypt.hash(user.password, salt, null, (err, hash) => {
if (err) return next(err)
user.password = hash
user.local.password = hash;
next()
})
})
})
/*
Defining our own custom document instance method
*/
UserSchema.methods = {
comparePassword: function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.local.password, (err, isMatch) => {
if (err) return cb(err)
cb(null, isMatch)
})
}
}
/**
* Statics
*/
UserSchema.statics = {}
module.exports = mongoose.model("User", UserSchema)

View File

@@ -0,0 +1,30 @@
.field {
padding-top: 10px;
padding-left: 5px;
padding-right: 5px;
}
/**
* The CSS shown here will not be introduced in the Quickstart guide, but shows
* how you can use CSS to style your Element's container.
*/
.StripeElement {
background-color: white;
height: 40px;
padding: 10px 12px;
border-radius: 5px;
border: 1px solid rgba(34,36,38,.15);
color: rgba(0,0,0,.87);
}
.StripeElement--focus {
border-color: #85b7d9;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}