Admin
+refresh
+-
+
- General +
- Thumbnails +
- Descriptions +
- Names +
diff --git a/package-lock.json b/package-lock.json index 7c0de356..28367af0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,6 +98,14 @@ "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "requires": { + "util": "0.10.3" + } + }, "assert-plus": { "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" @@ -145,6 +153,11 @@ "version": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" }, + "bcrypt-nodejs": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", + "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=" + }, "bcrypt-pbkdf": { "version": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", @@ -173,6 +186,11 @@ "version": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, "bmp-js": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.0.3.tgz", @@ -362,10 +380,24 @@ "version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookies": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz", + "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=", + "requires": { + "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "keygrip": "1.0.2" + } + }, "core-util-is": { "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "crc": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" + }, "cryptiles": { "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", @@ -662,6 +694,22 @@ "resolved": "https://registry.npmjs.org/express-recaptcha/-/express-recaptcha-3.0.1.tgz", "integrity": "sha1-b/a25u1D5u94ZD9W46qP/igDlMg=" }, + "express-session": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", + "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "requires": { + "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "crc": "3.4.4", + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "on-headers": "1.0.1", + "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "uid-safe": "2.1.5", + "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + } + }, "express-subdomain": { "version": "https://registry.npmjs.org/express-subdomain/-/express-subdomain-1.0.5.tgz", "integrity": "sha1-mQ75eUC39MKCPZWTZIt5voWKY4s=" @@ -1412,6 +1460,16 @@ "verror": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" } }, + "kareem": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.0.3.tgz", + "integrity": "sha512-WloXk3nyByx9FEB5WY7WFEXIZB/QA+zy7c2kJMjnZCebjepEyQcJzazgLiKcTS/ltZeEoeEQ1A1pau1fEDlnIA==" + }, + "keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha1-rTKXxVcGneqLz+ek+kkbdcXd65E=" + }, "kind-of": { "version": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", @@ -1499,6 +1557,11 @@ "lodash._root": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz" } }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.isarguments": { "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" @@ -1740,6 +1803,89 @@ } } }, + "mongoose": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.0.3.tgz", + "integrity": "sha512-y4NlLzZaQe5vJHjcEjHLKK6utjs7sVEPN971+d1vVJJGrmA+zeeFA1MEmC1J0ujD34eOSghnExXJPwCrxHHZCw==", + "requires": { + "async": "2.1.4", + "bson": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", + "kareem": "2.0.3", + "lodash.get": "4.4.2", + "mongodb": "3.0.2", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.3.0", + "mquery": "3.0.0", + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "requires": { + "lodash": "4.17.5" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "mongodb": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.2.tgz", + "integrity": "sha512-E50FmpSQchZAimn2uPIegoNoH9UQYR1yiGHtQPmmg8/Ekc97w6owHoqaBoz+assnd9V5LxMzmQ/VEWMsQMgZhQ==", + "requires": { + "mongodb-core": "3.0.2" + } + }, + "mongodb-core": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.2.tgz", + "integrity": "sha512-p1B0qwFQUw6C1OlFJnrOJp8KaX7MuGoogRbTaupRt0y+pPRkMllHWtE9V6i1CDtTvI3/3sy2sQwqWez7zuXEAA==", + "requires": { + "bson": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", + "require_optional": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz" + } + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mpath": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz", + "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q=" + }, + "mpromise": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz", + "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" + }, + "mquery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.0.0.tgz", + "integrity": "sha512-WL1Lk8v4l8VFSSwN3yCzY9TXw+fKVYKn6f+w86TRzOLSE8k1yTgGaLBPUByJQi8VcLbOdnUneFV/y3Kv874pnQ==", + "requires": { + "bluebird": "3.5.0", + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + }, + "dependencies": { + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + } + } + }, "ms": { "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" @@ -1855,6 +2001,11 @@ "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" } }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, "once": { "version": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", @@ -1966,6 +2117,28 @@ "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "requires": { + "passport-strategy": "1.0.0", + "pause": "0.0.1" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.0.0" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, "path-is-absolute": { "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" @@ -1989,6 +2162,11 @@ "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "performance-now": { "version": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" @@ -2046,6 +2224,11 @@ "version": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "randomatic": { "version": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", @@ -2142,6 +2325,11 @@ "is-equal-shallow": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz" } }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, "remove-trailing-separator": { "version": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" @@ -2280,6 +2468,11 @@ "version": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "sntp": { "version": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", @@ -2547,6 +2740,14 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "optional": true }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "1.0.0" + } + }, "uid2": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", @@ -2587,6 +2788,21 @@ "version": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, "util-deprecate": { "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" @@ -2624,6 +2840,11 @@ "extsprintf": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" } }, + "vhost": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vhost/-/vhost-3.0.2.tgz", + "integrity": "sha1-L7HezUxGaqiLD5NBrzPcGv8keNU=" + }, "vinyl": { "version": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", diff --git a/package.json b/package.json index 4d07f577..d60ed3e8 100644 --- a/package.json +++ b/package.json @@ -27,14 +27,18 @@ }, "homepage": "https://github.com/zoff-music/zoff#readme", "dependencies": { + "assert": "^1.4.1", "bad-words": "^1.5.1", + "bcrypt-nodejs": "0.0.3", "body-parser": "^1.17.1", "color-thief-jimp": "^2.0.2", "cookie-parser": "^1.4.3", + "cookies": "^0.7.1", "emoji-strip": "^0.0.3", "express": "^4.15.2", "express-handlebars": "^3.0.0", "express-recaptcha": "^3.0.1", + "express-session": "^1.15.6", "express-subdomain": "^1.0.5", "gulp": "^3.9.1", "gulp-concat": "^2.6.1", @@ -44,13 +48,18 @@ "mobile-detect": "^1.3.7", "mongodb": "^2.0.27", "mongojs": "^2.4.0", + "mongoose": "^5.0.3", + "mpromise": "^0.5.5", "node-cryptojs-aes": "^0.4.0", "nodemailer": "^4.0.1", + "passport": "^0.4.0", + "passport-local": "^1.0.0", "redis": "^2.8.0", "request": "^2.72.0", "socket.io": "^2.0.3", "socket.io-redis": "^5.2.0", "sticky-session": "^1.1.2", - "uniqid": "^4.1.1" + "uniqid": "^4.1.1", + "vhost": "^3.0.2" } } diff --git a/server/admin.js b/server/admin.js new file mode 100644 index 00000000..41be76b4 --- /dev/null +++ b/server/admin.js @@ -0,0 +1,215 @@ +var express = require('express'); +var app = express(); + +const path = require('path'); +const publicPath = path.join(__dirname, 'public'); +var exphbs = require('express-handlebars'); +var hbs = exphbs.create({ + defaultLayout: publicPath + '/layouts/admin/main', + layoutsDir: publicPath + '/layouts', + partialsDir: publicPath + '/partials' +}); + +var passport = require('passport'); +var mpromise = require('mpromise'); +var LocalStrategy = require('passport-local').Strategy; +var mongoose = require('mongoose'); +var mongo_db_cred = require(path.join(__dirname, './config/mongo_config.js')); +var mongojs = require('mongojs'); +var db = mongojs(mongo_db_cred.config); +var token_db = mongojs("tokens"); +var bodyParser = require('body-parser'); +var Cookies = require('cookies'); +var session = require('express-session'); +var api = require('./routing/admin/api.js'); + +var User = require('./models/user.js'); +var url = 'mongodb://localhost/users'; +mongoose.connect(url); + + +app.engine('handlebars', hbs.engine); +app.set('view engine', 'handlebars'); +app.enable('view cache'); +app.set('views', publicPath); +app.use(bodyParser.urlencoded({ + extended: true +})); +app.use(session({ + secret: mongo_db_cred.secret, + resave: true, + saveUninitialized: true +})); // session secret +app.use(passport.initialize()); +app.use(passport.session()); // persistent login sessions + +//app.use('/assets', express.static(publicPath + '/assets')); + +passport.serializeUser(function(user, done) { + done(null, user.id); +}); + + + +// used to deserialize the user +passport.deserializeUser(function(id, done) { + User.findById(id, function(err, user) { + done(err, user); + }); +}); + +passport.use('local-signup', new LocalStrategy({ + // by default, local strategy uses username and password, we will override with username + usernameField : 'username', + passwordField : 'password', + passReqToCallback : true // allows us to pass back the entire request to the callback +}, +function(req, username, password, done) { + // asynchronous + // User.findOne wont fire unless data is sent back + process.nextTick(function() { + + // find a user whose username is the same as the forms username + // we are checking to see if the user trying to login already exists + var token = req.param("token"); + token_db.collection("tokens").find({token: token}, function(err, docs){ + if(docs.length == 1){ + token_db.collection("tokens").remove({token: token}, function(err, docs){ + User.findOne({ 'username' : username }, function(err, user) { + // if there are any errors, return the error + if (err) + return done(err); + + // check to see if theres already a user with that username + if (user) { + return done(null, false); + } else { + + // if there is no user with that username + // create the user + var newUser = new User(); + + // set the user's local credentials + newUser.username = username; + newUser.password = newUser.generateHash(password); + + // save the user + newUser.save(function(err) { + if (err) + throw err; + return done(null, newUser); + }); + } + + }); + }); + } else { + return done(null, false); + } + }); + }); + +})); + +passport.use('local-login', new LocalStrategy({ + // by default, local strategy uses username and password, we will override with email + usernameField : 'username', + passwordField : 'password', + passReqToCallback : true // allows us to pass back the entire request to the callback +}, function(req, username, password, done) { // callback with email and password from our form + + // find a user whose email is the same as the forms email + // we are checking to see if the user trying to login already exists + User.findOne({ 'username' : username }, function(err, user) { + // if there are any errors, return the error before anything else + if (err) + return done(err); + + // if no user is found, return the message + if (!user) + return done(null, false); // req.flash is the way to set flashdata using connect-flash + + // if the user is found but the password is wrong + if (!user.validPassword(password)) + return done(null, false); // create the loginMessage and save it to session as flashdata + + // all is well, return successful user + + return done(null, user); + }); + +})); + +app.post('/signup', passport.authenticate('local-signup', { + successRedirect : '/', // redirect to the secure profile section + failureRedirect : '/signup', // redirect back to the signup page if there is an error + failureFlash : true // allow flash messages +})); + +app.post('/login', passport.authenticate('local-login', { + successRedirect : '/', // redirect to the secure profile section + failureRedirect : '/login', // redirect back to the signup page if there is an error + failureFlash : true // allow flash messages +})); + +app.use('/login', isLoggedInTryingToLogIn, function(req, res) { + var data = { + where_get: "not_authenticated" + }; + + res.render('layouts/admin/not_authenticated', data); +}); + +app.use('/signup', isLoggedInTryingToLogIn, function(req, res) { + var data = { + where_get: "not_authenticated" + }; + + res.render('layouts/admin/not_authenticated', data); +}); + +app.use('/', api); + +app.use('/logout', function(req, res) { + req.logout(); + res.redirect('/login'); +}); + +app.use('/assets', express.static(publicPath + '/assets')); + +app.use('/', isLoggedIn, function(req, res) { + var data = { + where_get: "authenticated", + year: new Date().getYear()+1900, + }; + + res.render('layouts/admin/authenticated', data); +}); + +function makeid() +{ + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for( var i=0; i < 20; i++ ) + text += possible.charAt(Math.floor(Math.random() * possible.length)); + + return text; +} + +function isLoggedInTryingToLogIn(req, res, next){ + if(!req.isAuthenticated()){ + return next(); + } + res.redirect("/"); +} + +function isLoggedIn(req, res, next) { + if (req.isAuthenticated()) + return next(); + res.redirect('/login'); +} + +//app.listen(default_port); + +module.exports = app; diff --git a/server/app.js b/server/app.js index 7ee7e126..5c2d7fc4 100644 --- a/server/app.js +++ b/server/app.js @@ -4,19 +4,23 @@ var cluster = require('cluster'), publicPath = path.join(__dirname, 'public'), http = require('http'), port = 8080, - num_processes = require('os').cpus().length; + num_processes = require('os').cpus().length, + express = require('express'), + vhost = require('vhost'), + app = express(); try { + a var redis = require("redis"); var client = redis.createClient({host: "localhost", port: 6379}); client.quit(); - startClustered(); + startClustered(true); } catch(e) { console.log("Couldn't connect to redis-server, assuming non-clustered run"); - startSingle(false); + startClustered(false); } -function startClustered() { +function startClustered(redis_enabled) { //Found https://stackoverflow.com/questions/40885592/use-node-js-cluster-with-socket-io-chat-application if (cluster.isMaster) { var workers = []; @@ -47,12 +51,13 @@ function startClustered() { worker.send('sticky-session:connection', connection); }).listen(port); } else { - startSingle(true); + startSingle(true, redis_enabled); } } -function startSingle(clustered) { - var app = require('./index.js'); +function startSingle(clustered, redis_enabled) { + var client = require('./client.js'); + var admin = require('./admin.js'); try { var cert_config = require(path.join(path.join(__dirname, 'config'), 'cert_config.js')); var fs = require('fs'); @@ -66,24 +71,47 @@ function startSingle(clustered) { }; var https = require('https'); - server = https.Server(credentials, app); + server = https.Server(credentials, client); } catch(err){ console.log("Starting without https (probably on localhost)"); - var http = require('http'); - server = http.Server(app); + server = http.Server(client); //add = ",http://localhost:80*,http://localhost:8080*,localhost:8080*, localhost:8082*,http://zoff.dev:80*,http://zoff.dev:8080*,zoff.dev:8080*, zoff.dev:8082*"; } + admin_server = http.Server(admin); + if(clustered) { - server.listen(onListen); + app + .use( vhost('*', function(req, res) { + server.emit("request", req, res); + }) ) + .use( vhost('remote.*', function(req, res) { + server.emit("request", req, res); + }) ) + .use( vhost('admin.*', function(req, res) { + admin_server.emit("request", req, res); + }) ) + .listen(onListen); + //server.listen(onListen); } else { - server.listen(port, onListen); + app + .use( vhost('*', function(req, res) { + server.emit("request", req, res); + }) ) + .use( vhost('remote.*', function(req, res) { + server.emit("request", req, res); + }) ) + .use( vhost('admin.*', function(req, res) { + admin_server.emit("request", req, res); + }) ) + .listen(port, onListen); + //server.listen(port, onListen); } - var socketIO = app.socketIO; + var socketIO = client.socketIO; - if(clustered) { + if(redis_enabled) { var redis = require('socket.io-redis'); try { socketIO.adapter(redis({ host: 'localhost', port: 6379 })); @@ -91,17 +119,18 @@ function startSingle(clustered) { console.log("No redis-server to connect to.."); } socketIO.listen(server); - process.on('message', function(message, connection) { - if (message !== 'sticky-session:connection') { - return; - } - server.emit('connection', connection); - - connection.resume(); - }); } else { socketIO.listen(server); } + + process.on('message', function(message, connection) { + if (message !== 'sticky-session:connection') { + return; + } + server.emit('connection', connection); + + connection.resume(); + }); } function onListen() { diff --git a/server/index.js b/server/client.js similarity index 93% rename from server/index.js rename to server/client.js index 97350459..5471d0b6 100755 --- a/server/index.js +++ b/server/client.js @@ -9,8 +9,8 @@ var app = express(); var exphbs = require('express-handlebars'); var hbs = exphbs.create({ - defaultLayout: publicPath + '/layouts/main', - layoutsDir: publicPath + '/layouts', + defaultLayout: publicPath + '/layouts/client/main', + layoutsDir: publicPath + '/layouts/client', partialsDir: publicPath + '/partials' }); uniqid = require('uniqid'); @@ -60,9 +60,9 @@ emojiStrip = require('emoji-strip'); Filter = require('bad-words'); filter = new Filter({ placeHolder: 'x'}); -var router = require('./routing/router.js'); -var api = require('./routing/api.js'); -var ico_router = require('./routing/icons_routing.js'); +var router = require('./routing/client/router.js'); +var api = require('./routing/client/api.js'); +var ico_router = require('./routing/client/icons_routing.js'); app.get('/robots.txt', function (req, res) { res.type('text/plain'); diff --git a/server/models/user.js b/server/models/user.js new file mode 100644 index 00000000..489c2efb --- /dev/null +++ b/server/models/user.js @@ -0,0 +1,24 @@ +// app/models/user.js +// load the things we need +var mongoose = require('mongoose'); +var bcrypt = require('bcrypt-nodejs'); + +// define the schema for our user model +var userSchema = mongoose.Schema({ + username : String, + password : String, +}); + +// methods ====================== +// generating a hash +userSchema.methods.generateHash = function(password) { + return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); +}; + +// checking if password is valid +userSchema.methods.validPassword = function(password) { + return bcrypt.compareSync(password, this.password); +}; + +// create the model for users and expose it to our app +module.exports = mongoose.model('User', userSchema); diff --git a/server/public/assets/admin/authenticated/js/main.js b/server/public/assets/admin/authenticated/js/main.js new file mode 100644 index 00000000..2fc14799 --- /dev/null +++ b/server/public/assets/admin/authenticated/js/main.js @@ -0,0 +1,527 @@ +var connection_options = { + 'sync disconnect on unload':true, + 'secure': true, + 'force new connection': true +}; +var socket = io.connect('https://zoff.me:8080', connection_options); + +$(document).ready(function(){ + $('ul.tabs').tabs(); + }); + +$(document).on("click", "#refresh_all", function(e){ + e.preventDefault(); + $("#descriptions_cont").empty(); + $("#thumbnails_cont").empty(); + if(!$(".channel_things").hasClass("hide")) { + $(".channel_things").addClass("hide") + } + $(".preloader-wrapper").removeClass("hide"); + $.ajax({ + type: "GET", + url: "/api/lists", + success: function(response){ + var output_pinned = ''; + var output_delete = ''; + for(var x = 0; x < response.length; x++){ + if(response[x].count > 5){ + output_pinned += ""; + } + output_delete += ""; + } + + $("#frontpage_pinned").html(output_pinned); + $("#remove_thumbnail").html(output_delete); + $("#remove_description").html(output_delete); + $("#delete_list_name").html(output_delete); + $("#delete_userpass_name").html(output_delete); + $("#delete_channel_name").html(output_delete); + $("select").material_select(); + $(".channel_things").removeClass("hide"); + if(!$(".preloader-wrapper").hasClass("hide")) { + $(".preloader-wrapper").addClass("hide"); + } + } + }); + + $.ajax({ + type: "GET", + url: "/api/thumbnails", + success: function(response){ + if(response.length > 0){ + $(".thumbnails-badge").removeClass("hide"); + $(".thumbnails-badge").text(response.length); + } + add_to_tab("thumbnails", response); + } + }); + + $.ajax({ + type: "GET", + url: "/api/descriptions", + success: function(response){ + if(response.length > 0){ + $(".descriptions-badge").removeClass("hide"); + $(".descriptions-badge").text(response.length); + } + add_to_tab("descriptions", response); + } + }); + + $("#listeners").empty(); + socket.emit("get_spread"); +}); + +socket.on("spread_listeners", function(obj){ + $("#listeners").append("
Private listeners: " + obj.offline + "
"); + $("#listeners").append("Total listeners: " + obj.total + "
"); + $("#listeners").append("" + obj.online_users[x]._id + ": " + obj.online_users[x].users.length + "
"); + } + } +}); + +if(!$(".channel_things").hasClass("hide")) { + $(".channel_things").addClass("hide") +} +$(".preloader-wrapper").removeClass("hide"); + +$.ajax({ + type: "GET", + url: "/api/lists", + success: function(response){ + var output_pinned = ''; + var output_delete = ''; + for(var x = 0; x < response.length; x++){ + if(response[x].count > 5){ + output_pinned += ""; + } + output_delete += ""; + } + + $("#frontpage_pinned").html(output_pinned); + $("#remove_thumbnail").html(output_delete); + $("#remove_description").html(output_delete); + $("#delete_list_name").html(output_delete); + $("#delete_userpass_name").html(output_delete); + $("#delete_channel_name").html(output_delete); + $("select").material_select(); + + if(!$(".preloader-wrapper").hasClass("hide")) { + $(".preloader-wrapper").addClass("hide") + } + $(".channel_things").removeClass("hide"); + } +}); + +$.ajax({ + type: "GET", + url: "/api/names", + success: function(response) { + for(var i = 0; i < response.length; i++) { + var icon = ""; + if(response[i].icon && response[i].icon != "") { + icon = "