diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..af0f0c3
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015"]
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 31081e3..e930b7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules/
.idea/
*.log.*
-uploads/
\ No newline at end of file
+uploads/
+package-lock.json
\ No newline at end of file
diff --git a/assets/css/common.css b/assets/css/common.css
deleted file mode 100755
index 9ec4f62..0000000
--- a/assets/css/common.css
+++ /dev/null
@@ -1,99 +0,0 @@
-html, body {
- height: 100%;
-}
-
-body {
- margin: 0;
-}
-
-* {
- font-family: focalpoint;
-}
-
-@font-face {
- font-family: focalpoint;
- src: url("/assets/fonts/Proxima-Nova-Semibold.woff2");
-}
-
-.flex-container {
- padding: 0;
- margin: 0;
- display: -webkit-box;
- display: -moz-box;
- display: -ms-flexbox;
- display: -webkit-flex;
- display: flex;
- flex-wrap: nowrap;
- flex-direction: column !important;
- justify-content: flex-start;
- align-items: center;
-}
-
-.row {
- margin: 0;
- display: -webkit-box;
- display: -moz-box;
- display: -ms-flexbox;
- display: -webkit-flex;
- display: flex;
- flex-direction: row;
- align-content: space-around;
- justify-content: flex-start;
- align-items: center;
- width: auto;
- padding: 8px;
-}
-
-.row > .row-item {
- margin: 5px;
-}
-
-.flex-item {
- text-align: center;
-}
-
-.right {
- float: right;
-}
-
-.inv {
- display: none;
-}
-
-.link {
- font-family: focalpoint;
- color: black;
- cursor: pointer;
- cursor: hand;
-}
-
-.link:hover > :first-child {
- color: #1799B5 !important;
-}
-
-.dropdown {
- position: relative;
- display: inline-block;
-}
-
-.dropdown-content {
- display: none;
- position: absolute;
- background-color: #f9f9f9;
- min-width: 160px;
- box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
- z-index: 2;
- margin-top: 10px;
-}
-
-.dropdown-content > * {
- padding: 12px 16px;
-}
-
-.dropdown:hover .dropdown-content {
- display: block;
-}
-
-.color-red {
- color: red;
-}
diff --git a/assets/img/classroom.jpeg b/assets/img/classroom.jpeg
deleted file mode 100755
index 7e47099..0000000
Binary files a/assets/img/classroom.jpeg and /dev/null differ
diff --git a/assets/img/classroom.svg b/assets/img/classroom.svg
deleted file mode 100755
index 5ed5ed7..0000000
--- a/assets/img/classroom.svg
+++ /dev/null
@@ -1,1967 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-image/svg+xml Openclipart 58294main_The.Brain.in.Space-page-47-kids-classroom 2010-04-06T07:38:20 This is clipart converted and broken apart that has been released into the public domain because the document says so, and its from NASA, a USA government agency. The publication is called "The Brain in Space:"
\n
\nhttp://www.nasa.gov/audience/foreducators/topnav/materials/listbytype/The.Brain.in.Space.html http://openclipart.org/detail/38197/-by-rejon-38197 rejon astronomy brain clip art clipart converted government nasa science space usa
diff --git a/assets/img/howls_moving_castle.png b/assets/img/howls_moving_castle.png
deleted file mode 100755
index ba9519a..0000000
Binary files a/assets/img/howls_moving_castle.png and /dev/null differ
diff --git a/assets/img/mountains.png b/assets/img/mountains.png
deleted file mode 100755
index 7d74724..0000000
Binary files a/assets/img/mountains.png and /dev/null differ
diff --git a/assets/img/parrot.png b/assets/img/parrot.png
deleted file mode 100755
index ea6eea7..0000000
Binary files a/assets/img/parrot.png and /dev/null differ
diff --git a/assets/js/api.js b/assets/js/api.js
deleted file mode 100755
index 9f65cb8..0000000
--- a/assets/js/api.js
+++ /dev/null
@@ -1,54 +0,0 @@
-let _api = { };
-
-axios.defaults.withCredentials = true;
-
-(function () {
- const root = 'http://localhost:3000/api/';
- const urls = {
- loginUrl: 'signin',
- logoutUrl: 'logout',
- currentUserUrl: 'current-user',
- videosUrl: 'videos'
- };
- function url(api) {
- return root + urls[api];
- }
-
- function get(url, params, fn) {
- axios.get(url, {
- params: params
- })
- .then(function (response) {
- fn(null, JSON.parse(response.data.split('\n')[1]));
- })
- .catch(function (error) {
- fn(JSON.parse(error.response.data.split('\n')[1]));
- });
- }
-
- function post(url, params, fn) {
- axios.post(url, params)
- .then(function (response) {
- fn(null, JSON.parse(response.data.split('\n')[1]));
- })
- .catch(function (error) {
- fn(JSON.parse(error.response.data.split('\n')[1]));
- });
- }
-
- _api.currentUser = function (fn) {
- get(url('currentUserUrl'), { }, fn);
- };
-
- _api.login = function (username, password, fn) {
- post(url('loginUrl'), { username: username, password: password }, fn);
- };
-
- _api.logout = function(fn) {
- post(url('logoutUrl'), {}, fn);
- };
-
- _api.videos = function(topicPath, accessLevel, offset, num, fn) {
- get(url('videosUrl'), { subject: topicPath.subject, course: topicPath.course, topic: topicPath.topic, accessLevel: accessLevel, offset: offset, num: num }, fn);
- };
-})();
diff --git a/assets/js/constants.js b/assets/js/constants.js
deleted file mode 100755
index f62dfcd..0000000
--- a/assets/js/constants.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const _const = {
- headerOne: {
- loginButton: 'Login / Create Account',
- profileButton: 'Current user',
- loginError: 'An error occurred. Please comtact support.'
- },
- videos: {
- num: 8
- }
-};
diff --git a/assets/js/utils.js b/assets/js/utils.js
deleted file mode 100755
index 3d26776..0000000
--- a/assets/js/utils.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const _utils = {
- page: {
-
- }
-};
\ No newline at end of file
diff --git a/index.html b/index.html
index b1fbe4f..378760b 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
Image Board
-
+
@@ -13,9 +13,7 @@
-
-
-
+
diff --git a/index.js b/index.js
index 700060a..f188548 100644
--- a/index.js
+++ b/index.js
@@ -5,6 +5,7 @@ const express = require('express'),
cookieParser = require('cookie-parser'),
PropertiesReader = require('properties-reader'),
multer = require('multer'),
+ path = require('path'),
passport = require('passport');
const app = express();
@@ -15,7 +16,7 @@ app.use(session({
secret: 'erferfre234324reevvfe',
resave: false,
saveUninitialized: true,
- cookie: { secure: false, maxAge: Number(100000) }
+ cookie: { secure: false, maxAge: Number(100000000) }
}));
app.use(passport.initialize());
app.use(passport.session());
@@ -30,15 +31,15 @@ global._isProd = _env === 'production';
console.info = function(message) {
console.log('[INFO] ' + message);
-}
+};
console.debug = function(message) {
console.log('[DEBUG] ' + message);
-}
+};
console.critical = function(message) {
console.log('[!!! CRITICAL !!!] ' + message);
-}
+};
const setUpDatabase = require(_base + 'services/SetupDatabaseService');
const setUpPassport = require(_base + 'services/SetUpPassport');
@@ -49,6 +50,10 @@ setUpPassport();
routescan(app, {
ignoreInvalid: true
});
+app.use('/dist', express.static('dist'));
+app.use('/src/assets', express.static('src/assets'));
+app.use('/uploads', express.static('uploads'));
+app.use((req, res) => res.sendFile(path.join(_base, '/index.html')));
app.use(function (err, req, res, next) {
console.debug('Error encountered: ' + err.message);
diff --git a/middleware/ensureAuthenticity.js b/middleware/ensureAuthenticity.js
index 8f65f05..4c71dcf 100644
--- a/middleware/ensureAuthenticity.js
+++ b/middleware/ensureAuthenticity.js
@@ -4,6 +4,6 @@ module.exports = function(req, res, next) {
if(req.isAuthenticated()) {
next();
} else {
- res.redirect("/login");
+ next(new Error('Not logged in.'));
}
-}
+};
\ No newline at end of file
diff --git a/models/board.js b/models/board.js
index bd33475..625bbef 100644
--- a/models/board.js
+++ b/models/board.js
@@ -2,7 +2,7 @@ let mongoose = require("mongoose");
let boardSchema = new mongoose.Schema({
- categoryName: { type: String, required: true, unique: true },
+ categoryName: { type: String, required: true },
name: { type: String, required: true, unique: true },
letter: { type: String, required: true, unique: true },
favIcon: { type: String }
diff --git a/models/mod.js b/models/mod.js
index 6e979b6..b2cbda7 100644
--- a/models/mod.js
+++ b/models/mod.js
@@ -1,22 +1,43 @@
let mongoose = require("mongoose"),
-// bcrypt = require("bcrypt"),
+ bcrypt = require("bcrypt-nodejs"),
shortid = require("shortid");
+const SALT_FACTOR = 4;
+
let modSchema = new mongoose.Schema({
_id: { type: String, required: true, default: shortid.generate },
- email: { type: String, required: true },
+ username: { type: String, required: true },
password: { type: String, required: true }
}, { collection: _db.get("db.collection.mods") });
-// TODO: implement check password method
-// modSchema.methods.checkPassword = function(guess, done) {
-// bcrypt.compare(guess, this.password, function(err, match) {
-// done(err, match);
-// });
-// };
-// TODO: remove this test implementation of the checkPassword method
+function noop() {};
+
+modSchema.pre('save', function (done) {
+ let user = this; //Reference to user model
+
+ if (!user.isModified("password")) {
+ return done();
+ }
+
+ bcrypt.genSalt(SALT_FACTOR, function (err, salt) {
+ if (err) {
+ return done(err);
+ }
+ bcrypt.hash(user.password, salt, noop, function (err, hashedPassword) {
+ if (err) {
+ return done(err);
+ }
+ user.password = hashedPassword;
+ done();
+ });
+ });
+});
+
modSchema.methods.checkPassword = function(guess, done) {
- done(null, true);
-}
+ bcrypt.compare(guess, this.password, function(err, isMatch) {
+ done(err, isMatch);
+ });
+};
+
let Mod = mongoose.model('Mod', modSchema);
module.exports = Mod;
diff --git a/models/reply.js b/models/reply.js
index f8c8b85..db3cee1 100644
--- a/models/reply.js
+++ b/models/reply.js
@@ -4,7 +4,11 @@ let shortid = require("shortid");
let replySchema = new mongoose.Schema({
_id: { type: String, required: true, default: shortid.generate },
time: { type: Date, required: true, default: Date.now },
- ip: { type: String, required: true }
+ ip: { type: String, required: true },
+ attachment_path: { type: String, required: false },
+ attachment_name: { type: String, required: false },
+ threadId: { type: String, required: true },
+ content: { type: String, required: false }
});
let Reply = mongoose.model("Reply", replySchema);
diff --git a/package.json b/package.json
index 3d3df71..75acf59 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,8 @@
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"server": "pm2 start index.js --watch --name server --ignore-watch 'uploads'",
- "vue": "cross-env NODE_ENV=development pm2 start webpack-dev-server --name vue -- --open --hot --inline --port 3002",
- "start": "npm run server | npm run vue",
+ "vue": "cross-env NODE_ENV=development pm2 start webpack-dev-server --name vue -- --open --hot --inline --port 3002 --host 0.0.0.0",
+ "start": "npm run server | npm run build",
"stop": "pm2 stop all",
"log": "pm2 log",
"restart": "npm run stop | npm run start | npm run log",
@@ -26,14 +26,18 @@
"express-session": "^1.15.6",
"express-validator": "^5.0.3",
"googleapis": "^27.0.0",
+ "ipaddr.js": "^1.6.0",
"mongoose": "^5.0.9",
+ "multer": "^1.3.0",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"properties-reader": "0.0.16",
"recaptcha": "^1.2.1",
+ "request-ip": "^2.0.2",
"shortid": "^2.2.8",
"string-format": "^0.5.0",
"striptags": "^3.1.1",
+ "transform-runtime": "0.0.0",
"validator": "^9.4.1",
"vue": "^2.5.11",
"vue-router": "^3.0.1"
@@ -49,6 +53,7 @@
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
+ "webpack-cli": "^2.0.14",
"webpack-dev-server": "^2.9.1"
}
}
diff --git a/routes/create/ban.js b/routes/create/ban.js
index 81c3906..38ed583 100644
--- a/routes/create/ban.js
+++ b/routes/create/ban.js
@@ -30,4 +30,4 @@ module.exports = {
}
}
-}
+};
diff --git a/routes/create/mod.js b/routes/create/mod.js
index 3e4d3c7..c4aabc2 100644
--- a/routes/create/mod.js
+++ b/routes/create/mod.js
@@ -4,9 +4,9 @@ module.exports = {
'/create/mod': {
methods: ['post'],
fn: function(req, res, next) {
- let email = req.body.email,
- password = req.body.passowrd;
- Mod.findOne({ email: email }, function(err, result) {
+ let username = req.body.username,
+ password = req.body.password;
+ Mod.findOne({ username: username }, function(err, result) {
if (err) {
return next(err);
}
@@ -14,8 +14,8 @@ module.exports = {
return next(new Mod("Mod with that email already exists"));
}
- let mod = new Mod({
- email: email,
+ let mod = new Mod({
+ username: username,
password: password
});
@@ -23,7 +23,7 @@ module.exports = {
if(err) {
return next(err);
}
- res.json({ result: { email: email } });
+ res.json({ result: { username: username } });
});
});
}
diff --git a/routes/create/reply.js b/routes/create/reply.js
index 2ad2eb2..76a3105 100644
--- a/routes/create/reply.js
+++ b/routes/create/reply.js
@@ -1,37 +1,54 @@
const Reply = require(_base + 'models/reply');
+const fs = require('fs');
+const path = 'uploads/';
+const multer = require('multer');
+const upload = multer({ dest: './uploads/'});
module.exports = {
- '/create/reply': {
+ '/create/reply' : {
methods: ['post'],
- fn: function(req, res, next) {
- let postId = req.body.id,
- content = req.body.content,
- attachment = req.body.attachment,
- time = req.body.time,
- ip = req.body.ip;
-
- Reply.findOne({ id: postId }, function(err, result) {
- if(err) {
- return next(err);
- }
-
- if(result) {
- return next(new Error("Reply with this id already exists"));
- }
-
- let reply = new Reply({ id: postId,
- content: content,
- attachment: attachment,
- time: time,
- ip: ip });
- reply.save(function(err) {
- if(err) {
- return next(err);
- }
- res.json({ id: postId, ip: ip});
- });
- });
-
+ middleware: [upload.single("attachment")],
+ fn: function (req, res, next) {
+ console.log(req.file);
+ let threadId = req.body.threadId,
+ attachment = req.file,
+ ip = req.connection.remoteAddress,
+ content = req.body.content;
+
+ let reply = new Reply({ threadId: threadId, ip: ip, content: content });
+
+ if (attachment) {
+ let target_path = path + attachment.filename + "." + attachment.originalname.split('.').pop();
+ reply.attachment_path = target_path;
+ reply.attachment_name = attachment.originalname;
+ }
+
+ reply.save(function(err) {
+ console.log(req.files);
+ if(err) {
+ return next(err);
+ }
+
+ if (attachment) {
+ //Save file to fs
+ fs.rename(attachment.path, target_path, function(err) {
+ if(err) {
+ return next(err);
+ }
+
+ fs.unlink(attachment.path, function() {
+ if(err) {
+ return next(err);
+ }
+
+ res.json({ result: { threadId: threadId, attachment_path: target_path, attachment_name: attachment.originalname, ip: ip, content: content } });
+ });
+ });
+ } else {
+ res.json({ result: { threadId: threadId, ip: ip, content: content } });
+ }
+
+ });
}
}
-}
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/routes/create/session.js b/routes/create/session.js
index 24ded05..538f1fb 100644
--- a/routes/create/session.js
+++ b/routes/create/session.js
@@ -3,14 +3,25 @@ const passport = require("passport");
module.exports = {
'/create/session': {
methods: ['post'],
- middleware: [
- passport.authenticate("login", {
- successRedirect: "/",
- failureRedirect: "/login",
- failureFlash: false
+ middleware: [passport.authenticate("login", {
+ successRedirect: "session/success",
+ failureRedirect: "session/fail",
+ failureFlash: false //Flash not needed
})],
- fn: function(req, res, next) {
-
+ fn: function (req, res, next) {
+
+ }
+ },
+ '/create/session/success': {
+ methods: ['get'],
+ fn: function (req, res, next) {
+ res.json({ result: 'Success' });
+ }
+ },
+ '/create/session/fail': {
+ methods: ['get'],
+ fn: function (req, res, next) {
+ next(new Error('Incorrect credentials.'));
}
}
-}
+};
diff --git a/routes/create/thread.js b/routes/create/thread.js
index 3c1f41c..a49d578 100644
--- a/routes/create/thread.js
+++ b/routes/create/thread.js
@@ -1,6 +1,6 @@
const Thread = require(_base + 'models/thread');
const fs = require('fs');
-const path = _base + 'uploads/'
+const path = 'uploads/';
const multer = require('multer');
const upload = multer({ dest: './uploads/'});
@@ -27,7 +27,7 @@ module.exports = {
return next(new Error('Thread with that name already exists.'));
}
- let target_path = path + attachment.filename + "." + attachment.originalname.split('.').pop();;
+ let target_path = path + attachment.filename + "." + attachment.originalname.split('.').pop();
let thread = new Thread({ name: name, boardId: board, attachment_path: target_path, attachment_name: attachment.originalname, pinned: pinned, ip: ip, content: content, title: title });
thread.save(function(err) {
console.log(req.files);
diff --git a/routes/read/boards.js b/routes/read/boards.js
index 9c3b75f..7fea40d 100644
--- a/routes/read/boards.js
+++ b/routes/read/boards.js
@@ -10,7 +10,7 @@ module.exports = {
letter = req.query.letter,
favicon = req.query.favicon;
- let boards = Boards.find({ letter: letter }, function(err, results) {
+ Boards.find({}, function(err, results) {
if (err) {
return next(err);
}
@@ -19,4 +19,4 @@ module.exports = {
});
}
}
-}
+};
diff --git a/routes/read/endSession.js b/routes/read/endSession.js
index cd13264..ccf8f03 100644
--- a/routes/read/endSession.js
+++ b/routes/read/endSession.js
@@ -1,11 +1,15 @@
const passport = require("passport");
module.exports = {
- 'read/endSession': {
+ '/read/endSession': {
methods: ['post'],
+ middleware: [],
fn: function(req, res, next) {
req.logout();
- res.redirect("/");
+ req.session.destroy(function(err) {
+ if (err) return next(err);
+ res.json({ result: 'Success' });
+ });
}
}
-}
+};
\ No newline at end of file
diff --git a/routes/read/replies.js b/routes/read/replies.js
index 3b9df6b..430676c 100644
--- a/routes/read/replies.js
+++ b/routes/read/replies.js
@@ -16,4 +16,4 @@ module.exports = {
}
}
-}
+};
diff --git a/routes/read/thread.js b/routes/read/thread.js
index 65769e3..bbbb625 100644
--- a/routes/read/thread.js
+++ b/routes/read/thread.js
@@ -4,17 +4,16 @@ module.exports = {
'/read/thread': {
methods: ['get'],
fn: function(req, res, next) {
- let letter = req.query.letter;
+ let _id = req.query._id;
//post id, name, content, pinned, time
- Threads.findOne({letter: letter}, function(err, result) {
+ console.log(_id);
+ Threads.findById(_id, function(err, result) {
if(err) {
return next(err);
} else {
- res.json({ result: { id: result.id, letter: letter, name: result.name,
- content: result.content, pinned: result.pinned,
- time: result.time } });
+ res.json({ result: result });
}
});
}
}
-}
+};
\ No newline at end of file
diff --git a/routes/read/threads.js b/routes/read/threads.js
index 68e1b09..dbc7663 100644
--- a/routes/read/threads.js
+++ b/routes/read/threads.js
@@ -5,7 +5,7 @@ module.exports = {
methods: ['get'],
fn: function(req, res, next) {
let letter = req.query.letter;
- Threads.find({ letter: letter }, function(err, results) {
+ Threads.find({ boardId: letter }, function(err, results) {
if(err) {
return next(err);
} else {
@@ -14,4 +14,4 @@ module.exports = {
});
}
}
-}
+};
\ No newline at end of file
diff --git a/routes/update/ban.js b/routes/update/ban.js
index a73be89..2dba473 100644
--- a/routes/update/ban.js
+++ b/routes/update/ban.js
@@ -3,7 +3,7 @@ const Ban = require(_base + 'models/ban');
module.exports = {
'/update/ban': {
methods: ['put'],
- middleware: [ensureAuthenticity],
+ middleware: [],
fn: function(req, res, next) {
let updateFields = {};
diff --git a/routes/update/board.js b/routes/update/board.js
index d79d878..8acb335 100644
--- a/routes/update/board.js
+++ b/routes/update/board.js
@@ -3,7 +3,7 @@ const Board = require(_base + 'models/board.js');
module.export = {
'/update/board': {
methods: ['put'],
- middleware: [ensureAuthenticity],
+ middleware: [],
fn: function(req, res, next) {
let updateFields = {};
diff --git a/routes/update/mod.js b/routes/update/mod.js
index 8fa914f..26aae7e 100644
--- a/routes/update/mod.js
+++ b/routes/update/mod.js
@@ -3,7 +3,7 @@ const Mod = require(_base + 'models/mod.js');
module.export = {
'/update/mod': {
methods: ['put'],
- middleware: [ensureAuthenticity],
+ middleware: [],
fn: function(req, res, next) {
let updateFields = {};
@@ -23,7 +23,7 @@ module.export = {
}
res.json({ result: result });
- }
+ });
}
}
diff --git a/services/SetUpPassport.js b/services/SetUpPassport.js
index 3213652..ecce8af 100644
--- a/services/SetUpPassport.js
+++ b/services/SetUpPassport.js
@@ -1,37 +1,39 @@
-let LocalStrategy = require('passport-local').Strategy,
- Mod = require(_base + 'models/mod'),
- passport = require("passport");
+var passport = require("passport");
-module.exports = function() {
- passport.serializeUser(function(mod, done) {
- done(null, mod._id);
- });
+var LocalStrategy = require("passport-local").Strategy;
- passport.deserializeUser(function(_id, done) {
- Mod.findById(_id, function(err, mod) {
- done(err, mod);
- });
- });
-}
-
-let strategy = new LocalStrategy({ usernameField: 'email' }, function(email, password, done) {
- Mod.findOne({ email: email }, function(err, mod) {
- if(err) {
- return done(err);
- } else if(!mod) {
- return done(null, false, { message: "No such mod of email " + email });
- }
+var User = require(_base + "models/mod");
- mod.checkPassword(password, function(err, matching) {
- if(err) {
- return done(err);
- } else if(match) {
- return done(null, mod);
- } else {
- return done(null, false, { message: "Incorrect password." })
- }
+module.exports = function () {
+ passport.serializeUser(function (user, done) {
+ done(null, user._id);
});
- });
-});
+ passport.deserializeUser(function (id, done) {
+ User.findById(id, function (err, user) {
+ done(err, user);
+ });
+ });
+};
-passport.use("login", strategy);
+passport.use("login", new LocalStrategy(function (username, password, done) {
+ User.findOne({ username: username }, function (err, user) {
+ if (err) {
+ return done(err);
+ }
+ if (!user) {
+ return done(null, false,
+ { message: "Invalid username or password." });
+ }
+ user.checkPassword(password, function (err, isMatch) {
+ if (err) {
+ return done(err);
+ }
+ if (isMatch) {
+ return done(null, user);
+ } else {
+ return done(null, false,
+ { message: "Invalid username or password." });
+ }
+ });
+ });
+}));
diff --git a/src/App.vue b/src/App.vue
index 75f4109..01d88a9 100755
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,8 +1,5 @@
-
-
Home
-
About
@@ -15,11 +12,6 @@ export default {
diff --git a/src/Router.js b/src/Router.js
index c3af0cb..b4ba6e1 100644
--- a/src/Router.js
+++ b/src/Router.js
@@ -1,33 +1,40 @@
import Vue from 'vue'
import Router from 'vue-router'
-import Index from './components/Index'
-import Catalog from './components/Catalog'
-import Thread from './components/Thread'
-import About from './components/About'
+import Index from './components/Index.vue'
+import Catalog from './components/Catalog.vue'
+import Thread from './components/Thread.vue'
+import About from './components/About.vue'
+import Login from './components/Login.vue'
-Vue.use(Router)
+Vue.use(Router);
export default new Router({
- routes: [
- {
- path: '/',
- name: 'Index',
- component: Index
- },
- {
- path: '/catalog/:board',
- name: 'Catalog',
- component: Catalog
- },
- {
- path: '/:board/thread/:thread'
- name: 'Thread',
- component: Thread
- },
- {
- path: '/about',
- name: 'About',
- component: About
- }
- ]
+ mode: 'history',
+ routes: [
+ {
+ path: '/',
+ name: 'Index',
+ component: Index
+ },
+ {
+ path: '/:board/catalog',
+ name: 'Catalog',
+ component: Catalog
+ },
+ {
+ path: '/:board/thread/:thread',
+ name: 'Thread',
+ component: Thread
+ },
+ {
+ path: '/about',
+ name: 'About',
+ component: About
+ },
+ {
+ path: '/login',
+ name: 'Login',
+ component: Login
+ }
+ ]
})
diff --git a/src/assets/css/common.css b/src/assets/css/common.css
new file mode 100755
index 0000000..47d5bae
--- /dev/null
+++ b/src/assets/css/common.css
@@ -0,0 +1,3 @@
+body {
+ background: #eef2ff url(http://s.4cdn.org/image/fade-blue.png) top center repeat-x;
+}
\ No newline at end of file
diff --git a/assets/fonts/Arial.ttf.woff b/src/assets/fonts/Arial.ttf.woff
similarity index 100%
rename from assets/fonts/Arial.ttf.woff
rename to src/assets/fonts/Arial.ttf.woff
diff --git a/assets/fonts/Proxima-Nova-Regular.woff2 b/src/assets/fonts/Proxima-Nova-Regular.woff2
similarity index 100%
rename from assets/fonts/Proxima-Nova-Regular.woff2
rename to src/assets/fonts/Proxima-Nova-Regular.woff2
diff --git a/assets/fonts/Proxima-Nova-Semibold.woff2 b/src/assets/fonts/Proxima-Nova-Semibold.woff2
similarity index 100%
rename from assets/fonts/Proxima-Nova-Semibold.woff2
rename to src/assets/fonts/Proxima-Nova-Semibold.woff2
diff --git a/src/assets/js/api.js b/src/assets/js/api.js
new file mode 100755
index 0000000..84eedb8
--- /dev/null
+++ b/src/assets/js/api.js
@@ -0,0 +1,69 @@
+let _api = { };
+
+axios.defaults.withCredentials = true;
+
+(function () {
+ const root = 'http://localhost:3001/';
+ const urls = {
+ loginUrl: 'create/session',
+ logoutUrl: 'read/endSession',
+ boardsUrl: 'read/boards',
+ threadsUrl: 'read/threads',
+ boardUrl: 'read/board',
+ threadUrl: 'read/thread',
+ repliesUrl: 'read/replies'
+ };
+ function url(api) {
+ return root + urls[api];
+ }
+
+ function get(url, params, fn) {
+ axios.get(url, {
+ params: params
+ })
+ .then(function (response) {
+ fn(null, response.data);
+ })
+ .catch(function (error) {
+ fn(error);
+ });
+ }
+
+ function post(url, params, fn) {
+ axios.post(url, params)
+ .then(function (response) {
+ fn(null, response.data);
+ })
+ .catch(function (error) {
+ fn(error);
+ });
+ }
+
+ _api.boards = function (fn) {
+ get(url('boardsUrl'), { }, fn);
+ };
+
+ _api.threads = function (letter, fn) {
+ get(url('threadsUrl'), { letter: letter }, fn);
+ };
+
+ _api.board = function (letter, fn) {
+ get(url('boardUrl'), { letter: letter }, fn);
+ };
+
+ _api.thread = function(id, fn) {
+ get(url('threadUrl'), { _id: id }, fn);
+ };
+
+ _api.replies = function(threadId, fn) {
+ get(url('repliesUrl'), { threadId: threadId }, fn);
+ };
+
+ _api.login = function (username, password, fn) {
+ post(url('loginUrl'), { username: username, password: password }, fn);
+ };
+
+ _api.logout = function(fn) {
+ post(url('logoutUrl'), {}, fn);
+ };
+})();
diff --git a/src/components/Catalog.vue b/src/components/Catalog.vue
index e69de29..b950870 100644
--- a/src/components/Catalog.vue
+++ b/src/components/Catalog.vue
@@ -0,0 +1,200 @@
+
+
+
+
+
+
/{{ $route.params.board }}/ {{ board.name }}
+
+
+
+
+
+
+
+
+ R: ?
+
+
+ Title: {{ thread.title }}
+
+
+
+
+
+
+
+ [
+
+ ]
+
+ [
+ Top
+ /
+ Home
+ ]
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Index.vue b/src/components/Index.vue
index 5af2e4c..4e7d26e 100644
--- a/src/components/Index.vue
+++ b/src/components/Index.vue
@@ -1,16 +1,150 @@
-
-
{{ msg }}
-
+
+
+
+
+
+
+
+
+
+
+
+
What is Image Board?
+
+
+
+
A simple image-based bulletin board where anyone can post comments and share images. There are boards dedicated to a variety of topics, from technology to politics, music, and science. Users do not need to register an account before participating in the community. Feel free to click on a board below that interests you and jump right in!
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Login.vue b/src/components/Login.vue
new file mode 100644
index 0000000..df03a3e
--- /dev/null
+++ b/src/components/Login.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Thread.vue b/src/components/Thread.vue
index e69de29..4684e2e 100644
--- a/src/components/Thread.vue
+++ b/src/components/Thread.vue
@@ -0,0 +1,288 @@
+
+
+
+
+
+
/{{ $route.params.board }}/ {{ board.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ thread.title }} Anonymous {{ new Date(thread.timeStamp) }}
+
No. {{ thread._id }}
+
+ {{ thread.content }}
+
+
+
+
+
+
+
>>
+
+
+
+
+
+
Anonymous {{ new Date(reply.time) }} No. {{ reply._id }}
+
+
{{ reply.content }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index fe7ad5d..a546fe2 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,78 +2,55 @@ var path = require('path')
var webpack = require('webpack')
module.exports = {
- entry: './src/main.js',
- output: {
- path: path.resolve(__dirname, './dist'),
- publicPath: '/dist/',
- filename: 'build.js'
- },
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [
- 'vue-style-loader',
- 'css-loader'
- ],
- }, {
- test: /\.vue$/,
- loader: 'vue-loader',
- options: {
- loaders: {
- }
- // other vue-loader options go here
- }
- },
- {
- test: /\.js$/,
- loader: 'babel-loader',
- exclude: /node_modules/
- },
- {
- test: /\.(png|jpg|gif|svg)$/,
- loader: 'file-loader',
- options: {
- name: '[name].[ext]?[hash]'
+ entry: './src/main.js',
+ output: {
+ path: path.resolve(__dirname, './dist'),
+ publicPath: '/dist/',
+ filename: 'build.js'
+ },
+ module: {
+ rules: [
+ {
+ test: /\.vue$/,
+ use: {
+ loader: 'vue-loader'
+ }
+ },
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader'
+ }
+ }
+ ]
+ },
+ resolve: {
+ alias: {
+ 'vue$': 'vue/dist/vue.esm.js'
}
- }
- ]
- },
- resolve: {
- alias: {
- 'vue$': 'vue/dist/vue.esm.js'
},
- extensions: ['*', '.js', '.vue', '.json']
- },
- devServer: {
- historyApiFallback: true,
- noInfo: true,
- overlay: true,
- disableHostCheck: true
- },
- performance: {
- hints: false
- },
- devtool: '#eval-source-map'
+ devServer: {
+ historyApiFallback: true,
+ noInfo: true
+ },
+ devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
- module.exports.devtool = '#source-map'
- // http://vue-loader.vuejs.org/en/workflow/production.html
- module.exports.plugins = (module.exports.plugins || []).concat([
- new webpack.DefinePlugin({
- 'process.env': {
- NODE_ENV: '"production"'
- }
- }),
- new webpack.optimize.UglifyJsPlugin({
- sourceMap: true,
- compress: {
- warnings: false
- }
- }),
- new webpack.LoaderOptionsPlugin({
- minimize: true
- })
- ])
-}
+ module.exports.devtool = '#source-map';
+ // http://vue-loader.vuejs.org/en/workflow/production.html
+ module.exports.plugins = (module.exports.plugins || []).concat([
+ new webpack.DefinePlugin({
+ 'process.env': {
+ NODE_ENV: '"production"'
+ }
+ }),
+ new webpack.optimize.UglifyJsPlugin({
+ compress: {
+ warnings: false
+ }
+ }),
+ new webpack.optimize.OccurrenceOrderPlugin()
+ ])
+}
\ No newline at end of file