Source: persistence.js


'use strict'

/**
Used to handle data persistence.
 * @module persistence
 */

const schema = require('../schema/schema')
const bcrypt = require('bcryptjs')

/** Checks to see if the supplied credentials are valid.
 * @function search
 * @param {Object} credentials the credentials object passed by the API
 * @param {Function(Error, String)} callback run on completion
 */
exports.validCredentials = (credentials, callback) => {
	if (credentials.username === undefined || credentials.password === undefined)
		callback(new Error('missing username and/or password'))
	schema.User.find({username: credentials.username}, (err, docs) => {
		if (err) callback(err)
		if (docs.length === 0) callback(null, false)
		console.log(docs[0])
		// need to test hash library
		// const saltStrength = 10
		// const salt = bcrypt.genSaltSync(saltStrength)
		// const pw = bcrypt.hashSync(credentials.password, salt)
		// console.log(`pw: ${pw}`)
		// end test
		console.log(`docs[0].password: ${docs[0].password}`)
		console.log(`credentials.password: ${credentials.password}`)
		if (!bcrypt.compareSync(credentials.password, docs[0].password)) {
			console.log('passwords dont match')
			callback(null, false)
			return
		}
		console.log('valid credentials')
		callback(null, true)
	})
}

/** Checks to see if the supplied credentials are valid.
 * @function validUsername
 * @param {Object}                  credentials the credentials object passed by the API
 * @param {Function(Error, String)} callback    run on completion
 */
exports.validUsername = (credentials, callback) => {
	if (credentials.username === undefined) {
		callback(new Error('missing username'))
		return
	}
	schema.User.find({username: credentials.username}, (err, docs) => {
		if (err) {
			callback(err)
			return
		}
		console.log(docs)
		if (docs.length === 0) {
			console.log('no matching username')
			callback(null, false)
			return
		}
		callback(null, true)
	})
}

/** Adds a new user account.
 * @function addAccount
 * @param {Object} credentials the credentials object passed by the API
 * @param {Object} user the additional user details (name)
 * @param {Function(Error, String)} callback run on completion
 */
exports.addAccount = (credentials, user, callback) => {
	console.log('addAccount')
	console.log(credentials)
	if (credentials.username === undefined || credentials.password === undefined) {
		callback(new Error('missing username and/or password'))
		return
	}
	if (user.name === undefined) {
		callback(new Error('missing name'))
		return
	}
	let account = undefined
	try {
		user.username = credentials.username
		const saltStrength = 10
		const salt = bcrypt.genSaltSync(saltStrength)
		user.password = bcrypt.hashSync(credentials.password, salt)
		account = new schema.User(user)
	} catch(err) {
		callback(err)
		return
	}
	account.save( (err, data) => {
		if (err) {
			callback(new Error('error creating account'))
			return
		}
		const user = {name: data.name, username: data.username}
		callback(null, user)
	})
}

/** Adds a book to the user's shopping cart.
 * @function addBookToCart
 * @param {Object}                  credentials the credentials object passed by the API
 * @param {Object}                  bookDetails the details of the book to add
 * @param {Function(Error, String)} callback    run on completion
 */
exports.addBook = (credentials, bookDetails, callback) => {
	if (credentials.username === undefined) {
		callback(new Error('missing username'))
		return
	}
	console.log(`username supplied: ${credentials.username}`)
	console.log(bookDetails)
	bookDetails.account = credentials.username
	const book = new schema.Book(bookDetails)
	book.save( (err, savedBook) => {
		if (err) {
			callback(err)
			return
		}
		callback(null, savedBook)
	})
}

/** gets the contents of the user's shopping cart.
 * @function addBookToCart
 * @param {Object}                  credentials the credentials object passed by the API
 * @param {Function(Error, String)} callback    run on completion
 */
exports.getBooksInCart = (credentials, callback) => {
	if (credentials.username === undefined || credentials.password === undefined) {
		callback(new Error('missing username and/or password'))
		return
	}
	this.validCredentials(credentials, (err, data) => {
		if (err) {
			callback(err)
			return
		}
		if (data === false) {
			callback(new Error('invalid credentials'))
			return
		}
		console.log('a')
		schema.Book.find({account: credentials.username}, (err, docs) => {
			console.log('b')
			if (err) {
				console.log('c')
				callback(err)
				return
			}
			console.log('d')
			console.log(docs.constructor)
			console.log(`docs.length: ${docs.length}`)
			if (docs.length < 1) {
				console.log('e')
				callback(new Error('shopping cart empty'))
				return
			}
			console.log('f')
			callback(null, docs)
		})
	})
}