Browse Source

Pushed what's done so far with implementing local auth without passport. Also added User Account Page.

theflametrooper 8 years ago
parent
commit
747f5a3fec

+ 2 - 46
backend/app.js

@@ -16,11 +16,7 @@ const express          = require('express'),
       cookieParser     = require('cookie-parser'),
       cors             = require('cors'),
       request          = require('request'),
-      passport         = require('passport'),
       bcrypt           = require('bcrypt'),
-      LocalStrategy    = require('passport-local').Strategy,
-      GitHubStrategy   = require('passport-github').Strategy,
-      DiscordStrategy  = require('passport-discord').Strategy,
       passportSocketIo = require("passport.socketio");
 
 // global module
@@ -59,47 +55,8 @@ globals.db.connection.once('open', _ => {
 		key: 'connect.sid',
 		store: globals.db.store,
 		resave: true,
-		saveUninitialized: true
-	}));
-
-	app.use(passport.initialize());
-	app.use(passport.session());
-
-	passport.serializeUser((user, done) => done(null, user));
-	passport.deserializeUser((user, done) => done(null, user));
-
-	globals.io.use(passportSocketIo.authorize({
-		passport: require('passport'),
-		cookieParser: require('cookie-parser'),
-		key: 'connect.sid',
-		secret: config.get('secret'),
-		store: globals.db.store,
-		success: (data, accept) => {
-			console.log('success', data);
-			accept();
-		},
-		fail: (data, message, error, accept) => {
-			console.log('error', error, message);
-			accept();
-		}
-	}));
-
-	passport.use(new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
-		process.nextTick(() => {
-			globals.db.models.user.findOne({ "email.address": email }, (err, user) => {
-				if (err) return done(err);
-				if (!user) return done(null, false);
-				bcrypt.compare(password, user.services.password.password, function(err, res) {
-					if (res) {
-						return done(null, user);
-					} else if (err) {
-						return done(err);
-					} else {
-						return done(null, false);
-					}
-				});
-			});
-		});
+		saveUninitialized: true,
+		cookie: { httpOnly: false }
 	}));
 
 	app.use(bodyParser.json());
@@ -114,4 +71,3 @@ globals.db.connection.once('open', _ => {
 	require('./logic/socketHandler')(coreHandler, globals.io);
 	require('./logic/expressHandler')(coreHandler, app);
 });
-

+ 52 - 1
backend/logic/coreHandler.js

@@ -130,8 +130,59 @@ module.exports = {
 		});
 	},
 
-	'/users/logout': (req, cb) => {
+	'/users/login': (session, identifier, password, cb) => {
+
+		waterfall([
+
+			// check if a user with the requested identifier exists
+			(next) => globals.db.models.user.findOne({
+				$or: [{ 'username': identifier }, { 'email.address': identifier }]
+			}, next),
+
+			// if the user doesn't exist, respond with a failure
+			// otherwise compare the requested password and the actual users password
+			(user, next) => {
+				if (!user) return next(true, { status: 'failure', message: 'User not found' });
+				bcrypt.compare(password, user.services.password.password, next);
+			},
 
+			// if the user exists, and the passwords match, respond with a success
+			(result, next) => {
+
+				// TODO: Authenticate the user with Passport here I think?
+				// TODO: We need to figure out how other login methods will work
+
+				next(null, {
+					status: result ? 'success': 'failure',
+					message: result ? 'Logged in' : 'User not found'
+				});
+			}
+
+		], (err, payload) => {
+			// log this error somewhere
+			if (err && err !== true) {
+				console.error(err);
+				return cb({ status: 'error', message: 'An error occurred while logging in' });
+			}
+			// respond with the payload that was passed to us earlier
+			cb(payload);
+		});
+
+	},
+
+	'/u/:username': (username, cb) => {
+		globals.db.models.user.find({ username }, (err, account) => {
+			if (err) throw err;
+			account = account[0];
+			cb({status: 'success', data: {
+				username: account.username,
+				createdAt: account.createdAt,
+				statistics: account.statistics
+			}});
+		});
+	},
+
+	'/users/logout': (req, cb) => {
 		if (!req.user || !req.user.logged_in) return cb({ status: 'failure', message: `You're not currently logged in` });
 
 		req.logout();

+ 4 - 2
backend/logic/expressHandler.js

@@ -4,9 +4,11 @@ const passport = require('passport');
 
 module.exports = (core, app) => {
 
-	app.post('/users/login', passport.authenticate('local'), (req, res) => {
+	app.post('/users/login', (req, res) => {
 		console.log('posted', req.user);
-  		res.json(JSON.stringify(req.user));
+		core['/users/login'](req.user, req.body.identifier, req.body.password, result => {
+ 			res.end(JSON.stringify(result));
+ 		});
 	});
 
 	app.post('/users/register', (req, res) => {

+ 4 - 2
backend/logic/socketHandler.js

@@ -8,7 +8,7 @@ module.exports = (core, io) => {
 
 		console.log("socketHandler: User has connected");
 
-		let session = socket.request.user;
+		let session = "socket.request.user";
 
 		socket.on('disconnect', _ => {
 			core['/stations/leave'](session, result => {});
@@ -19,6 +19,8 @@ module.exports = (core, io) => {
 
 		socket.on('/users/logout', (cb) => core['/users/logout'](socket.request, result => cb(result)));
 
+		socket.on('/u/:username', (cb) => core['/users/logout'](socket.request, result => cb(result)));
+
 		socket.on('/stations', (cb) => core['/stations'](session, result => cb(result)));
 		socket.on('/stations/join/:id', (id, cb) => core['/stations/join/:id'](session, id, result => cb(result)));
 		socket.on('/stations/leave', cb => core['/stations/leave'](session, result => cb(result)));
@@ -31,6 +33,6 @@ module.exports = (core, io) => {
 		socket.on('/youtube/getVideo/:query', (query, cb) => core['/youtube/getVideo/:query'](session, query, result => cb(result)));
 
 		// this lets the client socket know that they can start making request
-		socket.emit('ready', socket.request.user.logged_in);
+		socket.emit('ready', false); // socket.request.user.logged_in
 	});
 };

+ 3 - 1
backend/schemas/user.js

@@ -17,7 +17,9 @@ module.exports = {
 		bannedUntil: Date
 	},
 	statistics: {
-		songsRequested: { type: Number, default: 0 }
+		songsRequested: { type: Number, default: 0, required: true },
+		songsDisliked: [{ type: String, default: '', required: true }],
+		songsLiked: [{ type: String, default: '', required: true }]
 	},
 	createdAt: { type: Date, default: Date.now() }
 };

+ 1 - 1
frontend/App.vue

@@ -73,7 +73,7 @@
 					})
 				}).then(response => {
 					console.log(response);
-					// location.reload();
+					location.reload();
 				});
 			},
 			'joinStation': function(id) {

+ 0 - 0
frontend/components/AdminSongs.vue → frontend/components/Admin/Songs.vue


+ 0 - 0
frontend/components/AdminStations.vue → frontend/components/Admin/Stations.vue


+ 0 - 0
frontend/components/User/Settings.vue


+ 63 - 0
frontend/components/User/Show.vue

@@ -0,0 +1,63 @@
+<template>
+	<div class="container">
+		<img class="avatar" src="https://avatars2.githubusercontent.com/u/11198912?v=3&s=460"/>
+		<h1 class="has-text-centered">@{{user.username}}</h1>
+		<nav class="level">
+			<div class="level-item has-text-centered">
+				<p class="heading">Rank</p>
+				<p class="title">User</p>
+			</div>
+			<div class="level-item has-text-centered">
+				<p class="heading">Songs Requested</p>
+				<p class="title">{{requested}}</p>
+			</div>
+			<div class="level-item has-text-centered">
+				<p class="heading">Likes</p>
+				<p class="title">{{liked}}</p>
+			</div>
+			<div class="level-item has-text-centered">
+				<p class="heading">Dislikes</p>
+				<p class="title">{{disliked}}</p>
+			</div>
+		</nav>
+	</div>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				user: {},
+				liked: 0,
+				disliked: 0,
+				requested: 0
+			}
+		},
+		methods: {
+
+		},
+		ready: function() {
+			let local = this;
+			local.socket = local.$parent.socket;
+			local.socket.emit("/u/:username", local.$route.params.username, results => {
+				local.user = results.data;
+				local.liked = results.data.statistics.songsLiked.length;
+				local.disliked = local.user.statistics.songsDisliked.length;
+				local.requested = local.user.statistics.songsRequested;
+			});
+		}
+	}
+</script>
+
+<style lang="scss">
+	.avatar {
+		border-radius: 50%;
+		width: 250px;
+		display: block;
+		margin: auto;
+	}
+
+	.level {
+		margin-top: 40px;
+	}
+</style>

+ 5 - 5
frontend/components/pages/Admin.vue

@@ -17,8 +17,8 @@
 				</li>
 			</ul>
 		</div>
-		<admin-songs v-if="currentTab == 'songs'"></admin-songs>
-		<admin-stations v-if="currentTab == 'stations'"></admin-stations>
+		<songs v-if="currentTab == 'songs'"></songs>
+		<stations v-if="currentTab == 'stations'"></stations>
 	</div>
 </template>
 
@@ -26,11 +26,11 @@
 	import MainHeader from '../MainHeader.vue'
 	import MainFooter from '../MainFooter.vue'
 
-	import AdminSongs from '../AdminSongs.vue'
-	import AdminStations from '../AdminStations.vue'
+	import Songs from '../Admin/Songs.vue'
+	import Stations from '../Admin/Stations.vue'
 
 	export default {
-		components: { MainHeader, MainFooter, AdminSongs, AdminStations },
+		components: { MainHeader, MainFooter, Songs, Stations },
 		data() {
 			return {
 				currentTab: 'songs'

+ 1 - 1
frontend/components/pages/Home.vue

@@ -22,7 +22,7 @@
 					<p class="control">
 						<input class="input" type="password" placeholder="Password..." v-model="$parent.register.password">
 					</p>
-					<div class="g-recaptcha" data-sitekey="6Lfa-wYUAAAAANY6iVvWNEXohC38l1cZqHRole9T"></div>
+					<div class="g-recaptcha" data-sitekey="6LdNCQcUAAAAANj_w5leQSrxnAmDp2ioh4alkUHg"></div>
 				</section>
 				<footer class="modal-card-foot">
 					<a class="button is-primary" @click="submitModal('register')">Submit</a>

+ 10 - 0
frontend/main.js

@@ -1,9 +1,13 @@
 import Vue from 'vue';
 import VueRouter from 'vue-router';
+
 import App from './App.vue';
+
 import Home from './components/pages/Home.vue';
 import Station from './components/pages/Station.vue';
 import Admin from './components/pages/Admin.vue';
+import User from './components/User/Show.vue';
+import Settings from './components/User/Settings.vue';
 
 Vue.use(VueRouter);
 let router = new VueRouter({ history: true });
@@ -12,6 +16,12 @@ router.map({
 	'/': {
 		component: Home
 	},
+	'/u/:username': {
+		component: User
+	},
+	'/u/:username/settings': {
+		component: Settings
+	},
 	'/station/:id': {
 		component: Station
 	},