|
@@ -1,311 +0,0 @@
|
|
|
-'use strict';
|
|
|
-
|
|
|
-// nodejs modules
|
|
|
-const path = require('path'),
|
|
|
- fs = require('fs'),
|
|
|
- os = require('os'),
|
|
|
- events = require('events');
|
|
|
-
|
|
|
-// npm modules
|
|
|
-const config = require('config'),
|
|
|
- request = require('request'),
|
|
|
- waterfall = require('async/waterfall'),
|
|
|
- bcrypt = require('bcrypt'),
|
|
|
- passport = require('passport');
|
|
|
-
|
|
|
-// custom modules
|
|
|
-const globals = require('./globals'),
|
|
|
- stations = require('./stations');
|
|
|
-
|
|
|
-var eventEmitter = new events.EventEmitter();
|
|
|
-
|
|
|
-const edmStation = new stations.Station("edm", {
|
|
|
- "genres": ["edm"],
|
|
|
- playlist: [
|
|
|
- 'gCYcHz2k5x0'
|
|
|
- ],
|
|
|
- currentSongIndex: 0,
|
|
|
- paused: false,
|
|
|
- displayName: "EDM",
|
|
|
- description: "EDM Music"
|
|
|
-});
|
|
|
-
|
|
|
-const chillStation = new stations.Station("chill", {
|
|
|
- "genres": ["chill"],
|
|
|
- playlist: [
|
|
|
- 'gCYcHz2k5x0'
|
|
|
- ],
|
|
|
- currentSongIndex: 0,
|
|
|
- paused: false,
|
|
|
- displayName: "Chill",
|
|
|
- description: "Chill Music"
|
|
|
-});
|
|
|
-
|
|
|
-stations.addStation(edmStation);
|
|
|
-stations.addStation(chillStation);
|
|
|
-
|
|
|
-module.exports = {
|
|
|
-
|
|
|
- // module functions
|
|
|
-
|
|
|
- on: (name, cb) => eventEmitter.on(name, cb),
|
|
|
-
|
|
|
- emit: (name, data) => eventEmitter.emit(name, data),
|
|
|
-
|
|
|
- // core route handlers
|
|
|
-
|
|
|
- '/users/register': (user, username, email, password, recaptcha, cb) => {
|
|
|
-
|
|
|
- waterfall([
|
|
|
-
|
|
|
- // verify the request with google recaptcha
|
|
|
- (next) => {
|
|
|
- request({
|
|
|
- url: 'https://www.google.com/recaptcha/api/siteverify',
|
|
|
- method: 'POST',
|
|
|
- form: {
|
|
|
- 'secret': config.get("apis.recaptcha.secret"),
|
|
|
- 'response': recaptcha
|
|
|
- }
|
|
|
- }, next);
|
|
|
- },
|
|
|
-
|
|
|
- // check if the response from Google recaptcha is successful
|
|
|
- // if it is, we check if a user with the requested username already exists
|
|
|
- (response, body, next) => {
|
|
|
- let json = JSON.parse(body);
|
|
|
- console.log(json);
|
|
|
- if (json.success !== true) return next('Response from recaptcha was not successful');
|
|
|
- globals.db.models.user.findOne({ 'username': username }, next);
|
|
|
- },
|
|
|
-
|
|
|
- // if the user already exists, respond with that
|
|
|
- // otherwise check if a user with the requested email already exists
|
|
|
- (user, next) => {
|
|
|
- if (user) return next(true, { status: 'failure', message: 'A user with that username already exists' });
|
|
|
- globals.db.models.user.findOne({ 'email.address': email }, next);
|
|
|
- },
|
|
|
-
|
|
|
- // if the user already exists, respond with that
|
|
|
- // otherwise, generate a salt to use with hashing the new users password
|
|
|
- (user, next) => {
|
|
|
- if (user) return next(true, { status: 'failure', message: 'A user with that email already exists' });
|
|
|
- bcrypt.genSalt(10, next);
|
|
|
- },
|
|
|
-
|
|
|
- // hash the password
|
|
|
- (salt, next) => {
|
|
|
- bcrypt.hash(password, salt, next)
|
|
|
- },
|
|
|
-
|
|
|
- // save the new user to the database
|
|
|
- (hash, next) => {
|
|
|
- globals.db.models.user.create({
|
|
|
- username: username,
|
|
|
- email: {
|
|
|
- address: email,
|
|
|
- verificationToken: globals.utils.generateRandomString(64)
|
|
|
- },
|
|
|
- services: {
|
|
|
- password: {
|
|
|
- password: hash
|
|
|
- }
|
|
|
- }
|
|
|
- }, next);
|
|
|
- },
|
|
|
-
|
|
|
- // respond with the new user
|
|
|
- (newUser, next) => {
|
|
|
- next(null, { status: 'success', user: newUser })
|
|
|
- }
|
|
|
-
|
|
|
- ], (err, payload) => {
|
|
|
- // log this error somewhere
|
|
|
- if (err && err !== true) {
|
|
|
- console.error(err);
|
|
|
- return cb({ status: 'error', message: 'An error occurred while registering for an account' });
|
|
|
- }
|
|
|
- // respond with the payload that was passed to us earlier
|
|
|
- cb(payload);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- '/users/login': (user, 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();
|
|
|
-
|
|
|
- cb({ status: 'success', message: `You've been successfully logged out` });
|
|
|
- },
|
|
|
-
|
|
|
- '/stations': cb => {
|
|
|
- cb(stations.getStations().map(station => {
|
|
|
- return {
|
|
|
- id: station.id,
|
|
|
- playlist: station.playlist,
|
|
|
- displayName: station.displayName,
|
|
|
- description: station.description,
|
|
|
- currentSongIndex: station.currentSongIndex,
|
|
|
- users: station.users
|
|
|
- }
|
|
|
- }));
|
|
|
- },
|
|
|
-
|
|
|
- '/stations/join/:id': (id, cb) => {
|
|
|
-
|
|
|
- let station = stations.getStation(id);
|
|
|
-
|
|
|
- if (!station) return cb({ status: 'error', message: `Station with id '${id}' does not exist` });
|
|
|
-
|
|
|
- // session.station_id = id;
|
|
|
- station.users++;
|
|
|
-
|
|
|
- cb({ status: 'success', users: station.users });
|
|
|
- },
|
|
|
-
|
|
|
- // leaves the users current station
|
|
|
- // returns the count of users that are still in that station
|
|
|
- '/stations/leave': cb => {
|
|
|
-
|
|
|
- // let station = stations.getStation(session.station_id);
|
|
|
- let station = stations.getStation("edm"); // will be removed
|
|
|
- if (!station) return cb({ status: 'failure', message: `Not currently in a station, or station doesn't exist` });
|
|
|
-
|
|
|
- // session.station_id = "";
|
|
|
- // station.users--;
|
|
|
-
|
|
|
- cb({ status: 'success', users: station.users });
|
|
|
- },
|
|
|
-
|
|
|
- '/youtube/getVideo/:query': (query, cb) => {
|
|
|
-
|
|
|
- const params = [
|
|
|
- 'part=snippet',
|
|
|
- `q=${encodeURIComponent(query)}`,
|
|
|
- `key=${config.get('apis.youtube.key')}`,
|
|
|
- 'type=video',
|
|
|
- 'maxResults=15'
|
|
|
- ].join('&');
|
|
|
-
|
|
|
- request(`https://www.googleapis.com/youtube/v3/search?${params}`, (err, res, body) => {
|
|
|
-
|
|
|
- if (err) {
|
|
|
- console.error(err);
|
|
|
- return cb({ status: 'error', message: 'Failed to search youtube with the requested query' });
|
|
|
- }
|
|
|
-
|
|
|
- cb({ status: 'success', data: JSON.parse(body) });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- '/stations/add/:song': (station, song, cb) => {
|
|
|
-
|
|
|
- // if (!session.logged_in) return cb({ status: 'failure', message: 'You must be logged in to add a song' });
|
|
|
-
|
|
|
- const params = [
|
|
|
- 'part=snippet,contentDetails,statistics,status',
|
|
|
- `id=${encodeURIComponent(song.id)}`,
|
|
|
- `key=${config.get('apis.youtube.key')}`
|
|
|
- ].join('&');
|
|
|
-
|
|
|
- request(`https://www.googleapis.com/youtube/v3/videos?${params}`, (err, res, body) => {
|
|
|
-
|
|
|
- // TODO: Get data from Wikipedia and Spotify
|
|
|
-
|
|
|
- if (err) {
|
|
|
- console.error(err);
|
|
|
- return cb({ status: 'error', message: 'Failed to find song from youtube' });
|
|
|
- }
|
|
|
-
|
|
|
- const newSong = new globals.db.models.song({
|
|
|
- id: json.items[0].id,
|
|
|
- title: json.items[0].snippet.title,
|
|
|
- duration: globals.utils.convertTime(json.items[0].contentDetails.duration),
|
|
|
- thumbnail: json.items[0].snippet.thumbnails.high.url
|
|
|
- });
|
|
|
-
|
|
|
- // save the song to the database
|
|
|
- newSong.save(err => {
|
|
|
-
|
|
|
- if (err) {
|
|
|
- console.error(err);
|
|
|
- return cb({ status: 'error', message: 'Failed to save song from youtube to the database' });
|
|
|
- }
|
|
|
-
|
|
|
- stations.getStation(station).playlist.push(newSong);
|
|
|
-
|
|
|
- cb({ status: 'success', data: stations.getStation(station.playlist) });
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- '/songs': cb => {
|
|
|
- globals.db.models.song.find({}, (err, songs) => {
|
|
|
- if (err) throw err;
|
|
|
- cb(songs);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- '/songs/:song/update': (song, cb) => {
|
|
|
- globals.db.models.song.findOneAndUpdate({ id: song.id }, song, { upsert: true }, (err, updatedSong) => {
|
|
|
- if (err) throw err;
|
|
|
- cb(updatedSong);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- '/songs/:song/remove': (song, cb) => {
|
|
|
- globals.db.models.song.find({ id: song.id }).remove().exec();
|
|
|
- }
|
|
|
-};
|