Skip to content

Commit

Permalink
Merge pull request #107 from alexwohlbruck/develop
Browse files Browse the repository at this point in the history
1.1.2
  • Loading branch information
alexwohlbruck authored May 16, 2019
2 parents 89f398b + e7a05b7 commit 14cb953
Show file tree
Hide file tree
Showing 28 changed files with 1,124 additions and 1,132 deletions.
8 changes: 7 additions & 1 deletion app/config/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ module.exports = {

return `Thanks for signing up for ${semanticJoin(animalsList)} Facts! You will now receive fun facts about ${semanticJoin(animalsListCapital)} every day! =^.^=`;
},
animalTypes: [
'cat',
'dog',
'snail',
'horse'
],
unauthenticated: "Sign in first",
unauthorized: "You aren't allowed to do that!",
noVerificationCode: "Please provide a verification code",
Expand All @@ -23,5 +29,5 @@ module.exports = {
exists: "That person is already being facted"
},
invalidNumber: "That phone number is invalid!",
userPhotoUrl: "https://cat-fact.herokuapp.com/img/res/avatars/user-face.png"
userPhotoUrl: "https://cat-fact.herokuapp.com/img/res/avatars/user-face.png",
};
3 changes: 2 additions & 1 deletion app/models/fact.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongooseDelete = require('mongoose-delete');
const random = require('mongoose-simple-random');
const { animalTypes } = require('../config/strings.js');

const FactSchema = new Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'},
text: {type: String, required: true, unique: true},
sendDate: {type: Date},
used: {type: Boolean, default: false},
source: {type: String, enum: ['user', 'api'], default: 'user'},
type: {type: String, enum: ['cat', 'dog', 'snail', 'horse'], default: 'cat'}
type: {type: String, enum: animalTypes, default: 'cat'}
}, {
timestamps: true
});
Expand Down
6 changes: 3 additions & 3 deletions app/models/recipient.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const RecipientSchema = new Schema({
addedBy: {type: Schema.Types.ObjectId, ref: 'User'},
subscriptions: [{
type: String,
enum: ['cat', 'dog', 'snail', 'horse']
enum: strings.animalTypes // TODO: Move to constant definition
}]
}, {
timestamps: true
Expand Down Expand Up @@ -165,8 +165,8 @@ RecipientSchema.statics.addRecipients = async function ({authenticatedUser, requ

RecipientSchema.path('number').validate(function(number, done) {
this.model('Recipient').count({number: number}, function(err, count) {
if (err) return done(err);
done(!count);
if (err) return err;
return !count;
});
}, strings.recipient.exists);

Expand Down
11 changes: 4 additions & 7 deletions app/routes/catbot.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,10 @@ router.get('/daily', async (req, res) => {
};
};

// TODO: Define global list for animal types, use that to build this object
const facts = {
cat: getFactAndRecipients('cat'),
dog: getFactAndRecipients('dog'),
snail: getFactAndRecipients('snail'),
horse: getFactAndRecipients('horse')
};
const facts = {};
strings.animalTypes.forEach(animal => {
facts[animal] = getFactAndRecipients(animal);
});

const result = await Promise.props(facts),
dbMessages = [];
Expand Down
2 changes: 1 addition & 1 deletion app/routes/contact.routes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const express = require('express');
const router = express.Router();
const google = require('googleapis');
const { google } = require('googleapis');
const googleConfig = require.main.require('./app/config/google');
const googleContacts = google.people('v1');

Expand Down
10 changes: 5 additions & 5 deletions app/routes/fact.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ router.get('/', async (req, res) => {
const matchAll = {
$match: {
used: false,
// source: 'user',
source: 'user',
sendDate: {
$exists: false
},
Expand Down Expand Up @@ -62,9 +62,9 @@ router.get('/', async (req, res) => {
countUpvotes = [
{$addFields: {
upvotes: { $size: "$upvotes" },
userUpvoted: {
userUpvoted: req.user ? {
$in: [ req.user._id, "$upvotes.user" ]
}
} : undefined
}},
{$sort: {
upvotes: -1
Expand All @@ -81,12 +81,12 @@ router.get('/', async (req, res) => {
projectUpvotes,
...countUpvotes
]),
me: Fact.aggregate([
me: req.user ? Fact.aggregate([
matchMe,
lookupUpvotes,
projectUpvotes,
...countUpvotes
])
]) : undefined
});

return res.status(200).json(data);
Expand Down
78 changes: 78 additions & 0 deletions app/routes/recipient.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const IFTTTService = require.main.require('./app/services/ifttt.service.js');

const Recipient = require.main.require('./app/models/recipient');
const Message = require.main.require('./app/models/message');
const VerificationCode = require.main.require('./app/models/verification-code');


// Get all recipients
Expand Down Expand Up @@ -57,13 +58,33 @@ router.get('/me', isAuthenticated, async (req, res) => {
// Add new recipient(s)
router.post('/', isAuthenticated, async (req, res) => {

// TODO: Sanitize phone number input on server side

const requestedRecipients = req.body.recipients || [req.body.recipient];
const animalTypes = req.body.animalTypes;

/*
* requestedRecipients: [{
* name: String,
* number: String
* }],
* animalTypes: [String<Animal>]
*/

if (!requestedRecipients.length) {
return res.status(400).json({message: `No recipients provided`});
}

// If recipient already exists but is 'deleted', restore recipient to
// the new user account
const existingRecipients = await Recipient.findDeleted({number: {
$in: requestedRecipients.map(r => r.number)
}});

if (existingRecipients.length) {
existingRecipients.forEach(r => r.remove());
}

try {
const results = await Recipient.addRecipients({
authenticatedUser: req.user,
Expand All @@ -78,6 +99,33 @@ router.post('/', isAuthenticated, async (req, res) => {
}
});

// Restore recipient with new subscriptions
router.patch('/:recipientId/restore', isAuthenticated, async (req, res) => {

const recipientId = req.params.recipientId;
const resubscriptions = req.body.resubscriptions;

console.log(recipientId, resubscriptions);

try {
await Recipient.restore({_id: recipientId});

const recipient = await Recipient.findOneAndUpdate({_id: recipientId}, {
$set: {
subscriptions: resubscriptions
}
}, {
new: true
});
console.log(recipient);

return res.status(200).json(recipient);
}
catch (err) {
return res.status(err.status || 400).json(err);
}
});

router.patch('/:recipientId', isAuthenticated, async (req, res) => {

// TODO: only allow to edit recipient if user isAdmin or is addedBy them
Expand All @@ -98,6 +146,36 @@ router.patch('/:recipientId', isAuthenticated, async (req, res) => {
}
});

// Unsubscribe
router.delete('/me', isAuthenticated, async (req, res) => {

if (!req.query.verificationCode) {
return res.status(403).json({
message: strings.noVerificationCode
});
}

const submittedCode = req.query.verificationCode.trim();
const verificationCode = await VerificationCode.findOne({code: submittedCode});
const number = verificationCode ? verificationCode.data : undefined;

if (!verificationCode || !verificationCode.user.equals(req.user._id)) {
return res.status(403).json({
message: strings.invalidVerificationCode
});
}

await Recipient.delete({ number });
await VerificationCode.findByIdAndRemove(verificationCode._id);

const formattedPhone = `(${number.substr(0,3)}) ${number.substr(3,3)}-${number.substr(6,4)}`;

return res.status(200).json({
message: `Successfully unsubscribed ${formattedPhone}`
});
});

// Remove one or more recipients
router.delete('/', isAuthenticated, async (req, res) => {

const query = {_id: {$in: req.query.recipients}};
Expand Down
6 changes: 5 additions & 1 deletion app/routes/user.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ router.put('/me/profile/phone', isAuthenticated, async (req, res) => {
const submittedCode = req.body.verificationCode.trim();
const verificationCode = await VerificationCode.findOne({code: submittedCode});

if (!verificationCode) return res.status(403).json({message: strings.invalidVerificationCode});
if (!verificationCode || verificationCode.user != req.user._id) {
return res.status(403).json({
message: strings.invalidVerificationCode
});
}

const updatedUser = await User.findByIdAndUpdate(req.user._id, {$set: {
phone: verificationCode.data
Expand Down
Loading

0 comments on commit 14cb953

Please sign in to comment.