Compare commits
5 Commits
master
...
feature/ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
feb75faaad | ||
| 697b04a55b | |||
| dce868f2ac | |||
| cd6fa1fc06 | |||
| 77f836842b |
38
config.js
38
config.js
@@ -11,15 +11,22 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
version: '0.1.0',
|
version: '0.1.0',
|
||||||
assetStoreUrl: 'https://www.google.com/',
|
assetStoreUrl: 'https://www.google.com/',
|
||||||
services: {
|
mail: {
|
||||||
apple: {},
|
smtp: {
|
||||||
facebook: {
|
host: 'mail.fitz.guru',
|
||||||
appId: '2359355590971136',
|
port: 587,
|
||||||
appSecret: 'a5703f7d0af8e694aec5bd4175a85d6b',
|
secure: false,
|
||||||
|
auth: {
|
||||||
|
user: 'donotreply@eventment.io',
|
||||||
|
pass: '3ventment.eieio',
|
||||||
},
|
},
|
||||||
google: {
|
tls: {
|
||||||
appId: '442412638360-p0idffou0qlpgor7agideudb1dh10mpf.apps.googleusercontent.com',
|
rejectUnauthorized: false,
|
||||||
appSecret: 'a7fmS7Wc9Ssycr21WXdQ4TYl',
|
},
|
||||||
|
},
|
||||||
|
from: {
|
||||||
|
address: 'donotreply@eventment.io',
|
||||||
|
name: 'Eventment.io Support',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
security: {
|
security: {
|
||||||
@@ -33,5 +40,20 @@ module.exports = {
|
|||||||
route: '/reset',
|
route: '/reset',
|
||||||
tokenPlaceholder: ':reset_token',
|
tokenPlaceholder: ':reset_token',
|
||||||
},
|
},
|
||||||
|
confirm: {
|
||||||
|
route: '/confirm',
|
||||||
|
tokenPlaceholder: ':confirm_token',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
services: {
|
||||||
|
apple: {},
|
||||||
|
facebook: {
|
||||||
|
appId: '2359355590971136',
|
||||||
|
appSecret: 'a5703f7d0af8e694aec5bd4175a85d6b',
|
||||||
|
},
|
||||||
|
google: {
|
||||||
|
appId: '442412638360-p0idffou0qlpgor7agideudb1dh10mpf.apps.googleusercontent.com',
|
||||||
|
appSecret: 'a7fmS7Wc9Ssycr21WXdQ4TYl',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
28
emails/user.js
Normal file
28
emails/user.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
const config = require('../config');
|
||||||
|
const helpers = require('../lib/helpers');
|
||||||
|
const Mailer = require('../lib/Mailer');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
confirmation: ({ email, firstName, token }, callback = helpers.emptyFunction) => {
|
||||||
|
const link = `${config.api.url}${config.security.confirm.route}/${encodeURI(token)}`;
|
||||||
|
const mail = {
|
||||||
|
subject: 'Please confirm your account',
|
||||||
|
text: `Please confirm your account\r\r\r\r${firstName},\r\rAn account was recently created on the Eventment giving platform for this email (${email}).\r\rTo complete your registration, please open this link in your browser: ${link}\r\rIf you did not create this account, please disregard this email.`,
|
||||||
|
html: `<h2>Please confirm your account</h2><p>${firstName},</p><p>An account was recently created on the Eventment giving platform for this email (${email}).</p>To complete your registration, please <a href="${link}">click here</a>.</p><p><b>If you did not create this account, please disregard this email.</b></p>`,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mailer(email, mail, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: ({ email, firstName, token }, callback = helpers.emptyFunction) => {
|
||||||
|
const link = `${config.api.url}${config.security.reset.route}/${encodeURI(token)}`;
|
||||||
|
const mail = {
|
||||||
|
subject: 'Please confirm your account',
|
||||||
|
text: `Password Reset Request\r\r\r\r${firstName},\r\rA password reset request was made for your account on the Eventment giving platform.\r\rTo reset your password, please open this link in your browser: ${link}\r\rIf you did not make this request, you may disregard this email and your password will remain unchanged.`,
|
||||||
|
html: `<h2>Password Reset Request</h2><p>${firstName},</p><p>A password reset request was made for your account on the Eventment giving platform.</p>To reset your password, please <a href="${link}">click here</a>.</p><p><b>If you did not make this request, you may disregard this email and your password will remain unchanged.</b></p>`,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mailer(email, mail, callback);
|
||||||
|
},
|
||||||
|
};
|
||||||
17
lib/Mailer.js
Normal file
17
lib/Mailer.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const config = require('../config.js');
|
||||||
|
const nodemailer = require('nodemailer');
|
||||||
|
|
||||||
|
const from = `${config.mail.from.name} <${config.mail.from.address}>`;
|
||||||
|
const transporter = nodemailer.createTransport(config.mail.smtp);
|
||||||
|
|
||||||
|
module.exports = (email, options, callback) => {
|
||||||
|
callback = typeof callback === 'function' ? callback : (error, info) => {
|
||||||
|
if (error) {
|
||||||
|
return console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Message %s sent: %s', info.messageId, info.response);
|
||||||
|
};
|
||||||
|
|
||||||
|
transporter.sendMail({ to: email, from, ...options }, callback);
|
||||||
|
};
|
||||||
6
lib/helpers.js
Normal file
6
lib/helpers.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
|
||||||
|
emptyFunction: (...args) => args,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
76
models/auction.js
Normal file
76
models/auction.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
const timestamps = require('mongoose-timestamp');
|
||||||
|
|
||||||
|
const ItemAuctionStatusSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
bidCount: Number,
|
||||||
|
bidders: [ mongoose.Schema.Types.ObjectId ],
|
||||||
|
currentBid: Number,
|
||||||
|
currentMax: Number,
|
||||||
|
winners: [ mongoose.Schema.Types.ObjectId ],
|
||||||
|
},
|
||||||
|
{ minimize: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
const AuctionSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
eventId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
trim: true,
|
||||||
|
},
|
||||||
|
scoreboard: [ ItemAuctionStatusSchema ],
|
||||||
|
},
|
||||||
|
{ minimize: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
AuctionSchema.plugin(timestamps);
|
||||||
|
|
||||||
|
AuctionSchema.statics.getAuctionStatus = function(eventId, bidderId, callback = () => {}) {
|
||||||
|
this.findOne({ _id: eventId }, (err, event) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusObject = [];
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
statusObject.push(event.scoreboard.map((item) => ({
|
||||||
|
id: item._id,
|
||||||
|
bidCount: item.bidCount,
|
||||||
|
currentPrice: item.currentBid,
|
||||||
|
isBidding: item.bidders.indexOf(bidderId) > -1,
|
||||||
|
isWinning: item.winners.indexOf(bidderId) > -1,
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, statusObject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
AuctionSchema.statics.getAuctionItemStatus = function(eventId, itemId, bidderId, callback = () => {}) {
|
||||||
|
this.findOne({ _id: eventId }, (err, event) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemStatus = {};
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
const item = event.scoreboard.id(itemId);
|
||||||
|
if (item) {
|
||||||
|
itemStatus._id = item._id;
|
||||||
|
itemStatus.bidCount = item.bidCount;
|
||||||
|
itemStatus.currentPrice = item.currentBid;
|
||||||
|
itemStatus.isBidding = item.bidders.indexOf(bidderId) > -1;
|
||||||
|
itemStatus.isWinning = item.winners.indexOf(bidderId) > -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, itemStatus);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const Auction = mongoose.model('Auction', AuctionSchema);
|
||||||
|
module.exports = Auction;
|
||||||
@@ -3,6 +3,11 @@ const timestamps = require('mongoose-timestamp');
|
|||||||
|
|
||||||
const BidSchema = new mongoose.Schema(
|
const BidSchema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
|
eventId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
trim: true,
|
||||||
|
},
|
||||||
itemId: {
|
itemId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
const config = require('../config.js');
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const timestamps = require('mongoose-timestamp');
|
const timestamps = require('mongoose-timestamp');
|
||||||
|
|
||||||
|
const config = require('../config.js');
|
||||||
|
const Item = require('./item');
|
||||||
|
|
||||||
const PostSchema = new mongoose.Schema(
|
const PostSchema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
author: String,
|
author: String,
|
||||||
@@ -133,7 +135,11 @@ const EventSchema = new mongoose.Schema(
|
|||||||
|
|
||||||
EventSchema.plugin(timestamps);
|
EventSchema.plugin(timestamps);
|
||||||
|
|
||||||
EventSchema.path('images').get(v => `${config.assetStoreUrl}${v.url}`)
|
EventSchema.path('images').get(v => `${config.assetStoreUrl}${v.url}`);
|
||||||
|
|
||||||
|
EventSchema.methods.getEventAuctionItems = function(callback = () => {}) {
|
||||||
|
return Item.getAuctionItemsByEvent(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
const Event = mongoose.model('Event', EventSchema);
|
const Event = mongoose.model('Event', EventSchema);
|
||||||
module.exports = Event;
|
module.exports = Event;
|
||||||
|
|||||||
@@ -131,5 +131,9 @@ ItemSchema.statics.addBatch = function(data = [], callback = () => {}) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ItemSchema.statics.getAuctionItemsByEvent = function(eventId, callback = () => {}) {
|
||||||
|
return this.find({ eventId, type: 'auction' }, callback);
|
||||||
|
};
|
||||||
|
|
||||||
const Item = mongoose.model('Item', ItemSchema);
|
const Item = mongoose.model('Item', ItemSchema);
|
||||||
module.exports = Item;
|
module.exports = Item;
|
||||||
|
|||||||
114
models/user.js
114
models/user.js
@@ -5,6 +5,7 @@ const timestamps = require('mongoose-timestamp');
|
|||||||
|
|
||||||
const config = require('../config.js');
|
const config = require('../config.js');
|
||||||
|
|
||||||
|
const UserEmails = require('../emails/user');
|
||||||
const AddressSchema = require('./common/address.js');
|
const AddressSchema = require('./common/address.js');
|
||||||
const PhoneSchema = require('./common/phone.js');
|
const PhoneSchema = require('./common/phone.js');
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ const UserSchema = new mongoose.Schema(
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
resetCheckBit: {
|
tokenCheckBit: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
@@ -127,11 +128,30 @@ UserSchema.methods.authenticate = function (username, password) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.methods.isNomAvailable = function (nom) {
|
UserSchema.methods.confirmRegistration = function (callback = () => {}) {
|
||||||
return !!!this.model('User').findOne({ nomDeBid });
|
this.isVerified = true;
|
||||||
|
this.tokenCheckBit = undefined;
|
||||||
|
this.save(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.methods.generateJWT = function (props = {}) {
|
UserSchema.methods.generateAccountToken = function (callback = () => {}) {
|
||||||
|
const tokenCheckBit = crypto.randomBytes(16).toString('hex');
|
||||||
|
const token = jwt.sign({
|
||||||
|
sub: this.id,
|
||||||
|
key: tokenCheckBit,
|
||||||
|
iss: config.security.jwt.issuer,
|
||||||
|
aud: config.security.jwt.audience,
|
||||||
|
iat: Date.now(),
|
||||||
|
exp: (Date.now() + (24*60*60*1000)),
|
||||||
|
}, config.security.jwt.secret);
|
||||||
|
|
||||||
|
this.tokenCheckBit = tokenCheckBit;
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
return token;
|
||||||
|
};
|
||||||
|
|
||||||
|
UserSchema.methods.generateLoginToken = function (props = {}) {
|
||||||
const { exp, iss } = props;
|
const { exp, iss } = props;
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
|
||||||
@@ -160,33 +180,20 @@ UserSchema.methods.getNomDeBid = function () {
|
|||||||
return this.nomDeBid || `${this.firstName} ${this.lastName.charAt(0)}`;
|
return this.nomDeBid || `${this.firstName} ${this.lastName.charAt(0)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.methods.generateResetToken = function (callback = () => {}) {
|
|
||||||
const resetCheckBit = crypto.randomBytes(16).toString('hex');
|
|
||||||
const token = jwt.sign({
|
|
||||||
sub: this.id,
|
|
||||||
key: resetCheckBit,
|
|
||||||
iss:config.security.jwt.issuer,
|
|
||||||
aud: config.security.jwt.audience,
|
|
||||||
iat: Date.now(),
|
|
||||||
exp: (Date.now() + (24*60*60*1000)),
|
|
||||||
}, config.security.jwt.secret);
|
|
||||||
|
|
||||||
this.resetCheckBit = resetCheckBit;
|
|
||||||
this.save();
|
|
||||||
|
|
||||||
return token;
|
|
||||||
};
|
|
||||||
|
|
||||||
UserSchema.methods.isEventManager = function () {
|
UserSchema.methods.isEventManager = function () {
|
||||||
return this.isOrganizationEmployee || false;
|
return this.isOrganizationEmployee || false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UserSchema.methods.isNomAvailable = function (nom) {
|
||||||
|
return !!!this.model('User').findOne({ nomDeBid });
|
||||||
|
};
|
||||||
|
|
||||||
UserSchema.methods.isRegistrationVerified = function () {
|
UserSchema.methods.isRegistrationVerified = function () {
|
||||||
return this.isVerified || false;
|
return this.isVerified || false;
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.methods.sendPasswordReset = function () {
|
UserSchema.methods.sendPasswordReset = function () {
|
||||||
const resetToken = this.generateResetToken();
|
const resetToken = this.generateAccountToken();
|
||||||
|
|
||||||
let resetRoute = config.security.resetRoute;
|
let resetRoute = config.security.resetRoute;
|
||||||
resetRoute = resetRoute.replace(':user_id', this.id);
|
resetRoute = resetRoute.replace(':user_id', this.id);
|
||||||
@@ -196,6 +203,19 @@ UserSchema.methods.sendPasswordReset = function () {
|
|||||||
console.log('[sendPasswordReset] resetUrl:', resetUrl);
|
console.log('[sendPasswordReset] resetUrl:', resetUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UserSchema.methods.sendConfirmationEmail = function (callback) {
|
||||||
|
const user = {
|
||||||
|
email: this.email,
|
||||||
|
firstName: this.firstName,
|
||||||
|
token: this.generateAccountToken(),
|
||||||
|
};
|
||||||
|
|
||||||
|
callback = typeof callback === 'function' ? callback :
|
||||||
|
(err, info) => console.log('[UserSchema.methods.sendConfirmationEmail]', { err, info });
|
||||||
|
|
||||||
|
UserEmails.confirmation(user, callback);
|
||||||
|
};
|
||||||
|
|
||||||
UserSchema.methods.setNomDeBid = function (nomDeBid, callback = () => {}) {
|
UserSchema.methods.setNomDeBid = function (nomDeBid, callback = () => {}) {
|
||||||
const alreadyExists = this.isNomAvailable(nomDeBid);
|
const alreadyExists = this.isNomAvailable(nomDeBid);
|
||||||
|
|
||||||
@@ -223,7 +243,7 @@ UserSchema.methods.setPassword = function (password, callback = () => {}) {
|
|||||||
if (hasLocalStrategy) {
|
if (hasLocalStrategy) {
|
||||||
this.model('User').findOneAndUpdate(
|
this.model('User').findOneAndUpdate(
|
||||||
{ _id: this._id, 'credentials.method': 'local' },
|
{ _id: this._id, 'credentials.method': 'local' },
|
||||||
{ $set: { 'credentials.$': strategy, resetCheckBit: null } },
|
{ $set: { 'credentials.$': strategy }, $unset: { tokenCheckBit: '' } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
@@ -231,7 +251,7 @@ UserSchema.methods.setPassword = function (password, callback = () => {}) {
|
|||||||
|
|
||||||
if (!hasLocalStrategy) {
|
if (!hasLocalStrategy) {
|
||||||
this.credentials.push(strategy);
|
this.credentials.push(strategy);
|
||||||
this.resetCheckBit = null;
|
this.tokenCheckBit = undefined;
|
||||||
this.save(callback);
|
this.save(callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -242,8 +262,9 @@ UserSchema.methods.toAuthJSON = function () {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
email: this.email,
|
email: this.email,
|
||||||
token: this.generateJWT(),
|
token: this.generateLoginToken(),
|
||||||
user: {
|
user: {
|
||||||
|
id: this._id,
|
||||||
nomDeBid: nomDeBid,
|
nomDeBid: nomDeBid,
|
||||||
email: this.email,
|
email: this.email,
|
||||||
firstName: this.firstName,
|
firstName: this.firstName,
|
||||||
@@ -266,6 +287,11 @@ UserSchema.methods.toProfileJSON = function () {
|
|||||||
email: this.email,
|
email: this.email,
|
||||||
firstName: this.firstName,
|
firstName: this.firstName,
|
||||||
generatedNomDeBid: !hasNomDeBid,
|
generatedNomDeBid: !hasNomDeBid,
|
||||||
|
hasLinkedApple: !!this.getAuthStrategy('apple'),
|
||||||
|
hasLinkedFacebook: !!this.getAuthStrategy('facebook'),
|
||||||
|
hasLinkedGoogle: !!this.getAuthStrategy('google'),
|
||||||
|
hasLocalAccount: !!this.getAuthStrategy('local'),
|
||||||
|
id: this.id,
|
||||||
isAllowedToBid: this.isAllowedToBid,
|
isAllowedToBid: this.isAllowedToBid,
|
||||||
isOrganizationEmployee: this.isOrganizationEmployee,
|
isOrganizationEmployee: this.isOrganizationEmployee,
|
||||||
isVerified: this.isVerified,
|
isVerified: this.isVerified,
|
||||||
@@ -348,14 +374,32 @@ UserSchema.statics.findOneAndUpdateOrCreate = function (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.statics.verifyResetToken = function (token, callback) {
|
UserSchema.statics.register = function (user, callback = () => {}) {
|
||||||
|
this.create(user, (err, user) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
user.sendConfirmationEmail((err, info) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
UserSchema.statics.verifyAccountToken = function (token, callback) {
|
||||||
jwt.verify(token, config.security.jwt.secret, (err, decoded) => {
|
jwt.verify(token, config.security.jwt.secret, (err, decoded) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { sub, key } = decoded;
|
const { sub, key } = decoded;
|
||||||
this.findOne({ _id: sub, resetCheckBit: key }, (err, user) => {
|
this.findOne({ _id: sub, tokenCheckBit: key }, (err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -370,7 +414,7 @@ UserSchema.statics.verifyResetToken = function (token, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.statics.verifyTokenAndResetPassword = function (token, password, callback) {
|
UserSchema.statics.verifyTokenAndResetPassword = function (token, password, callback) {
|
||||||
this.verifyResetToken(token, (err, user, info) => {
|
this.verifyAccountToken(token, (err, user, info) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -383,6 +427,20 @@ UserSchema.statics.verifyTokenAndResetPassword = function (token, password, call
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UserSchema.statics.verifyTokenAndConfirmRegistration = function (token, callback) {
|
||||||
|
this.verifyAccountToken(token, (err, user, info) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return callback(err, false, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.confirmRegistration(callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PATH OPERATIONS
|
* PATH OPERATIONS
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"mongoose": "^5.6.0",
|
"mongoose": "^5.6.0",
|
||||||
"mongoose-timestamp": "^0.6.0",
|
"mongoose-timestamp": "^0.6.0",
|
||||||
|
"nodemailer": "^6.3.0",
|
||||||
"passport": "^0.4.0",
|
"passport": "^0.4.0",
|
||||||
"passport-facebook": "^3.0.0",
|
"passport-facebook": "^3.0.0",
|
||||||
"passport-google-oauth": "^2.0.0",
|
"passport-google-oauth": "^2.0.0",
|
||||||
|
|||||||
43
routes/auction.js
Normal file
43
routes/auction.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
const errors = require('restify-errors');
|
||||||
|
|
||||||
|
const config = require('../config');
|
||||||
|
const Auction = require('../models/auction');
|
||||||
|
const Bid = require('../models/bid');
|
||||||
|
const User = require('../models/user');
|
||||||
|
|
||||||
|
module.exports = function (server, auth) {
|
||||||
|
|
||||||
|
server.get('/auction', auth.basic, function (req, res, next) {
|
||||||
|
Auction.getAuctionStatus(null, req.user.bidderId, (err, doc) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(doc);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get('/auction/:event_id', auth.basic, function (req, res, next) {
|
||||||
|
Auction.getAuctionStatus(req.params.event_id, req.user.bidderId, (err, doc) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(doc);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get('/auction/:event_id/:item_id', auth.basic, function (req, res, next) {
|
||||||
|
const { event_id: eventId, item_id: itemId } = req.params;
|
||||||
|
Auction.getAuctionItemStatus(eventId, itemId, req.user.bidderId, (err, doc) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(doc);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
module.exports = function(server, auth) {
|
module.exports = function(server, auth) {
|
||||||
|
require('./auction.js')(server, auth);
|
||||||
require('./auth.js')(server, auth);
|
require('./auth.js')(server, auth);
|
||||||
require('./bids.js')(server, auth);
|
require('./bids.js')(server, auth);
|
||||||
require('./demo.js')(server, auth);
|
require('./demo.js')(server, auth);
|
||||||
@@ -7,5 +8,6 @@ module.exports = function(server, auth) {
|
|||||||
require('./items.js')(server, auth);
|
require('./items.js')(server, auth);
|
||||||
require('./reset.js')(server, auth);
|
require('./reset.js')(server, auth);
|
||||||
require('./sales.js')(server, auth);
|
require('./sales.js')(server, auth);
|
||||||
|
require('./signup.js')(server, auth);
|
||||||
require('./users.js')(server, auth);
|
require('./users.js')(server, auth);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ module.exports = function (server, auth) {
|
|||||||
|
|
||||||
server.get('/items', auth.basic, (req, res, next) => {
|
server.get('/items', auth.basic, (req, res, next) => {
|
||||||
const select = req.user.isManager ? STAFF : PUBLIC;
|
const select = req.user.isManager ? STAFF : PUBLIC;
|
||||||
|
|
||||||
Item.find(req.params, select, function(err, docs) {
|
Item.find(req.params, select, function(err, docs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ const routes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function (server, auth) {
|
module.exports = function (server, auth) {
|
||||||
server.get(routes.getTestToken, auth.secure, function (req, res, next) {
|
server.get(routes.getTestToken, auth.basic, function (req, res, next) {
|
||||||
const { record: user } = req.user;
|
const { record: user } = req.user;
|
||||||
const resetToken = user.generateResetToken();
|
const resetToken = user.generateAccountToken();
|
||||||
const resetUrl = `${url}${route}/${resetToken}`;
|
const resetUrl = `${url}${route}/${resetToken}`;
|
||||||
|
|
||||||
res.send({ resetToken, resetUrl });
|
res.send({ resetToken, resetUrl });
|
||||||
@@ -26,7 +26,7 @@ module.exports = function (server, auth) {
|
|||||||
|
|
||||||
server.post(routes.resetWithToken, auth.bypass, function (req, res, next) {
|
server.post(routes.resetWithToken, auth.bypass, function (req, res, next) {
|
||||||
const { reset_token } = req.params;
|
const { reset_token } = req.params;
|
||||||
const { password } = req.body;
|
const { body: { password } = {}} = req;
|
||||||
|
|
||||||
if (!reset_token) {
|
if (!reset_token) {
|
||||||
return next(
|
return next(
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ const User = require('../models/user');
|
|||||||
module.exports = function (server, auth) {
|
module.exports = function (server, auth) {
|
||||||
const { passport } = auth;
|
const { passport } = auth;
|
||||||
|
|
||||||
server.post('/signup', (req, res, next) => {
|
server.post('/signup', auth.basic, (req, res, next) => {
|
||||||
const { body: { user = null } = {} } = req;
|
const { body: { user = null } = {} } = req;
|
||||||
|
|
||||||
let errors = {};
|
let errors = {};
|
||||||
let errorCount = 0;
|
let errorCount = 0;
|
||||||
if (!user) {
|
if (!user) {
|
||||||
errors.user = 'is required - can\'t make something from nothing...'';
|
errors.user = `is required - can't make something from nothing...`;
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,13 +21,13 @@ module.exports = function (server, auth) {
|
|||||||
|
|
||||||
User.register(user, (err, user, info) => {
|
User.register(user, (err, user, info) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
res.send(200, {
|
res.send(200, {
|
||||||
success: false,
|
success: false,
|
||||||
nextSteps: 'Please fix the problems indicated and try again.'
|
nextSteps: 'Please fix the problems indicated and try again.',
|
||||||
...info
|
...info
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,9 +36,44 @@ module.exports = function (server, auth) {
|
|||||||
|
|
||||||
res.send(200, {
|
res.send(200, {
|
||||||
success: true,
|
success: true,
|
||||||
nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.'
|
nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get('/signup/confirm/:token([A-Za-z0-9_]+\.{3})', (req, res, next) => {
|
||||||
|
const { token } = req.params;
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return next(
|
||||||
|
new errors.InvalidContentError('A confirmation token was not provided.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
User.verifyTokenAndConfirmRegistration(token, (err, user, info) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return next(
|
||||||
|
new errors.InvalidContentError(err),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
console.error(err);
|
||||||
|
res.send({
|
||||||
|
success: false,
|
||||||
|
info: `Account registration confirmation failed. ${info}`,
|
||||||
|
});
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
success: true,
|
||||||
|
info: 'New account registration confirmed.',
|
||||||
|
...user.toAuthJSON()
|
||||||
|
});
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ module.exports = function (server, auth) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/users', auth.manager, (req, res, next) => {
|
server.get('/users', auth.basic, (req, res, next) => {
|
||||||
const { filter } = aqp(req.query);
|
const { filter } = aqp(req.query);
|
||||||
const select = req.user.isManager ? STAFF : PUBLIC;
|
const select = req.user.isManager ? STAFF : PUBLIC;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ module.exports = function (server, auth) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send(doc);
|
res.send(req.user.isManager ? doc : doc.toProfileJSON());
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const createRequestUserObject = (req, user) => ({
|
const createRequestUserObject = (req, user) => ({
|
||||||
|
bidderId: user.id || null,
|
||||||
isGuest: !(user && user.id),
|
isGuest: !(user && user.id),
|
||||||
isManager: user && user.isEventManager(),
|
isManager: user && user.isEventManager(),
|
||||||
isSelf: user && user.id === req.params.user_id,
|
isSelf: user && user.id === req.params.user_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user