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

finished #21

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

MONGODB_URI=mongodb://heroku_2z2z3hh5:[email protected]:41406/heroku_2z2z3hh5
MONGOLAB_RED_URI=mongodb://heroku_77f3xdxs:[email protected]:39446/heroku_77f3xdxs
MONGOLAB_WHITE_URI=mongodb://heroku_s3fd16pl:[email protected]:37686/heroku_s3fd16pl
NODE_ENV=production
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ----------------------------------------
# NPM
# ----------------------------------------

node_modules/
npm-debug.log


# ----------------------------------------
# ENV now included for heroku deployment
# ----------------------------------------
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node app.js
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
# Ponz.io
Building Ponz.io, with its endearingly upside-down-triangle-shaped business model.
# Customer Referral Site Source Code

A customer referral site that utilizes Dynamically-generated URLS for referrals

Features:
- Display of referrals that your referrals created
- Generates a unique 'referral' url for each user
- User authentification and 'points' accounting with a NoSQL database

## Deployed Site

Check out this project at: https://secret-atoll-15400.herokuapp.com

## Key Technologies Used and Technical Challenges

Key Technologies used:
- unique URL creation
- Heroku
- NoSQL Databases
- ExpressJS

Challenges:
- Display of Users referred (i.e. create the 'nesting' of users referred by user's referrals see picture 2) -> utilized a 'deep populate' function from Mongoose (similar to a SQL join) and a recursive function to determine the 'depth'/'nesting' of users

## Demo

![Alt text](./images/1.png?raw=true "Title")
![Alt text](./images/2.png?raw=true "Title")

## Deployment

### Prerequisites

What things you need to install the software and how to install them

* node
* npm
* mongodb

### How to deploy this on your local machine

```
git clone <project-folder-on-github>
cd <cloned-project-folder-on-your-local-machine>
npm install
nodemon app.js
```

## Authors

* **Steven Li** - _Initial work_ -
210 changes: 210 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
const express = require("express");
const app = express();

// ----------------------------------------
// App Variables
// ----------------------------------------
app.locals.appName = "Ponzi.io";

// ----------------------------------------
// ENV
// ----------------------------------------
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}

// ----------------------------------------
// Body Parser
// ----------------------------------------
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));

// ----------------------------------------
// Sessions/Cookies
// ----------------------------------------
const cookieSession = require("cookie-session");

app.use(
cookieSession({
name: "session",
keys: [process.env.SESSION_SECRET || "secret"]
})
);

app.use((req, res, next) => {
res.locals.session = req.session;
next();
});

// ----------------------------------------
// Flash Messages
// ----------------------------------------
const flash = require("express-flash-messages");
app.use(flash());

// ----------------------------------------
// Method Override
// ----------------------------------------
const methodOverride = require("method-override");
const getPostSupport = require("express-method-override-get-post-support");

app.use(
methodOverride(
getPostSupport.callback,
getPostSupport.options // { methods: ['POST', 'GET'] }
)
);

// ----------------------------------------
// Referrer
// ----------------------------------------
app.use((req, res, next) => {
req.session.backUrl = req.header("Referer") || "/";
next();
});

// ----------------------------------------
// Public
// ----------------------------------------
app.use(express.static(`${__dirname}/public`));

// ----------------------------------------
// Logging
// ----------------------------------------
const morgan = require("morgan");
const morganToolkit = require("morgan-toolkit")(morgan);

app.use(morganToolkit());

//-----------------------------------------
//Mongoose Settings
//-----------------------------------------
const {User} = require("./models");
const mongoose = require("mongoose");

console.log("mongoose stuff intialized");

app.use((req, res, next) => {
console.log("use for mongoose callback");
if (mongoose.connection.readyState) {
console.log("if (mongoose.connection.readyState)");
next();
} else {
console.log("else (mongoose.connection.readyState)");
require("./mongo")().then(() => next());
console.log("else (mongoose.connection.readyState)");
}
});

// ----------------------------------------
// Local Passport
// ----------------------------------------
const passport = require("passport");
app.use(passport.initialize());
app.use(passport.session());
console.log("passport stuff initialize");

const LocalStrategy = require("passport-local").Strategy;

//see this post on why local strategy was changed
//https://stackoverflow.com/questions/34511021/passport-js-missing-credentials
//old local strategy
// passport.use(
// new LocalStrategy(function(email, password, done) {
// User.findOne({ email }, function(err, user) {
// if (err) return done(err);
// if (!user || !user.validPassword(password)) {
// return done(null, false, { message: 'Invalid email/password' });
// }
// return done(null, user);
// });
// })
// );

passport.use(
new LocalStrategy(
{
usernameField: "email",
passwordField: "password"
},
function(email, password, done) {
User.findOne({email}, function(err, user) {
if (err) return done(err);
if (!user || !user.validPassword(password)) {
return done(null, false, {message: "Invalid email/password"});
}
return done(null, user);
});
}
)
);

passport.serializeUser(function(user, done) {
done(null, user.id);
});

passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});

// ----------------------------------------
// Routes
// ----------------------------------------
const home = require("./routers/home");
app.use("/", home);

const ponversion = require("./routers/ponversion");
app.use("/ponvert", ponversion);

const triangle = require("./routers/triangle");
app.use("/triangle", triangle);

// ----------------------------------------
// Template Engine
// ----------------------------------------
const expressHandlebars = require("express-handlebars");
const helpers = require("./helpers");

const hbs = expressHandlebars.create({
helpers: helpers,
partialsDir: "views/", //this is how to use partials - any file in views can be rendered as a partial
defaultLayout: "application"
});

app.engine("handlebars", hbs.engine);
app.set("view engine", "handlebars");

// ----------------------------------------
// Server
// ----------------------------------------
const port = process.env.PORT || process.argv[2] || 3000;
const host = "localhost";

let args;
process.env.NODE_ENV === "production" ? (args = [port]) : (args = [port, host]);

args.push(() => {
console.log(`Listening: http://${host}:${port}\n`);
});

if (require.main === module) {
app.listen.apply(app, args);
}

// ----------------------------------------
// Error Handling
// ----------------------------------------
app.use((err, req, res, next) => {
if (res.headersSent) {
return next(err);
}

if (err.stack) {
err = err.stack;
}
res.status(500).render("errors/500", {error: err});
});

module.exports = app;
1 change: 1 addition & 0 deletions config/.keep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.keep
13 changes: 13 additions & 0 deletions config/mongo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"development": {
"database": "ponzie_development",
"host": "localhost"
},
"test": {
"database": "ponzie_test",
"host": "localhost"
},
"production": {
"use_env_variable": "MONGODB_URI"
}
}
19 changes: 19 additions & 0 deletions helpers/application_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const ApplicationHelper = {};


ApplicationHelper.rootPath = () => '/';
ApplicationHelper.CSSID = (...args) => {
let n = args.length;
let options = args[n - 1];
let viewPath = options.data.exphbs.view;
let id = viewPath.split('/').join('-');
return id;
};


module.exports = ApplicationHelper;





13 changes: 13 additions & 0 deletions helpers/bootstrap_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const BootstrapHelper = {};


BootstrapHelper.glyphicon = type => {
return `<span
class="glyphicon
glyphicon-${ type }"
aria-hidden="true"></span>`
};



module.exports = BootstrapHelper;
14 changes: 14 additions & 0 deletions helpers/flash_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const FlashHelper = {};


FlashHelper.bootstrapAlertClassFor = key => {
return {
"error": "danger",
"alert": "danger",
"notice": "info"
}[key] || key;
};


module.exports = FlashHelper;

9 changes: 9 additions & 0 deletions helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const LoadHelpers = require('load-helpers');
const helperLoader = new LoadHelpers();
const helpers = helperLoader.load('helpers/*_helper.js').cache;

module.exports = helpers;




19 changes: 19 additions & 0 deletions helpers/lodash_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const _ = require('lodash');


const LodashHelper = {};


LodashHelper.isEmpty = _.isEmpty;
LodashHelper.size = _.size;



module.exports = LodashHelper;







14 changes: 14 additions & 0 deletions helpers/math_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

const MathHelper = {};


MathHelper.add = (a, b) => a + b;
MathHelper.sub = (a, b) => a - b;
MathHelper.div = (a, b) => a / b;
MathHelper.mult = (a, b) => a * b;



module.exports = MathHelper;


Loading