Skip to content

Commit

Permalink
Merge pull request #79 from alexwohlbruck/cleanup
Browse files Browse the repository at this point in the history
Delete account option in settings (Fixes #73)
  • Loading branch information
alexwohlbruck authored Apr 22, 2018
2 parents 94ecff8 + 2b48925 commit 813f401
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 36 deletions.
38 changes: 19 additions & 19 deletions app/config/passport.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,36 @@ module.exports = passport => {
},
(req, accessToken, refreshToken, profile, done) => {

User.findOne({'google.id': profile.id}, (err, user) => {

const name = {
first: profile.name.givenName,
last: profile.name.familyName
},
email = profile.emails[0].value,
photo = profile.photos[0] && !profile._json.image.isDefault
? profile.photos[0].value.replace("?sz=50", "?sz=200")
: strings.userPhotoUrl,
google = {
id: profile.id,
accessToken: User.encryptAccessToken(accessToken),
refreshToken
},
ip = req.clientIp;
const name = {
first: profile.name.givenName,
last: profile.name.familyName
},
email = profile.emails[0].value,
photo = profile.photos[0] && !profile._json.image.isDefault
? profile.photos[0].value.replace("?sz=50", "?sz=200")
: strings.userPhotoUrl,

google = {
id: profile.id,
accessToken: User.encryptAccessToken(accessToken),
refreshToken
},
ip = req.clientIp;

User.findOne({'email': email}, (err, user) => {

if (err) return done(err);

if (!user) {

console.log('did not find user creating new')
user = new User({name, photo, email, google, ip});
user.save(err => {
if (err) console.log(err);
return done(err, user);
});

} else {

console.log('user already exists')
User.findByIdAndUpdate(user._id, {
'google.accessToken': User.encryptAccessToken(accessToken),
'google.refreshToken': refreshToken,
Expand Down
29 changes: 21 additions & 8 deletions app/models/user.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crypto = require('crypto');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const crypto = require('crypto');
const mongooseDelete = require('mongoose-delete');

var keys = require.main.require('./app/config/keys');
var strings = require.main.require('./app/config/strings');
const keys = require.main.require('./app/config/keys');
const strings = require.main.require('./app/config/strings');

var UserSchema = new Schema({
// Make email and phone docs unique except for those that are flagged as deleted
const uniquePartialIndex = {
unique: true,
partialFilterExpression: {
deleted: false
}
};

const UserSchema = new Schema({
name: {
first: {type: String, required: true},
last: {type: String, required: true}
},
email: {type: String, unique: true, sparse: true},
phone: {type: String, unique: true, sparse: true},
email: {type: String},
phone: {type: String},
photo: {type: String, default: strings.userPhotoUrl},
google: {
id: {type: String},
Expand Down Expand Up @@ -44,6 +53,10 @@ UserSchema.statics.decryptAccessToken = function(cipher) {
.update(cipher, 'hex', 'utf-8');
};

UserSchema.plugin(mongooseDelete, {overrideMethods: true});

UserSchema.index({email: 1, phone: 1}, uniquePartialIndex);

var User = mongoose.model('User', UserSchema);

module.exports = User;
2 changes: 1 addition & 1 deletion app/routes/fact.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ router.get('/:factID', async (req, res) => {
});

// Submit a fact
router.post('/submitted', async (req, res) => {
router.post('/', async (req, res) => {
if (!req.user) {
return res.status(401).json({message: strings.unauthenticated});
}
Expand Down
2 changes: 1 addition & 1 deletion app/routes/recipient.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ router.get('/:number/conversation', async (req, res) => {
if (results[0]) {
return res.status(200).json(results[1]);
} else {
return res.status(401).json({message: "You aren't facting this person"});
return res.status(403).json({message: "You aren't facting this person"});
}
}

Expand Down
21 changes: 20 additions & 1 deletion app/routes/user.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ router.get('/me', (req, res) => {
return res.status(401).json(false);
});

router.delete('/me', async (req, res) => {
// Confirm intention to delete by checking inputted email
if (!req.user)
return res.status(401).json({message: strings.unauthenticated});

if (req.user.email !== req.query.verificationEmail)
return res.status(403).json({message: 'Email addresses do not match'});


try {
await User.delete({_id: req.user._id});
return res.status(200).json({message: 'Account deleted'});
}
catch (err) {
return res.status(200).json({message: err.message || 'Failed to delete account', err});
}

});

router.put('/me/settings', async (req, res) => {
if (!req.user) return res.status(401).json({message: strings.unauthenticated});

Expand Down Expand Up @@ -55,7 +74,7 @@ router.post('/me/profile/phone/verification-code', async (req, res) => {

router.put('/me/profile/phone', async (req, res) => {
if (!req.user) return res.status(401).json({message: strings.unauthenticated});
if (!req.body.verificationCode) return res.status(401).json({message: strings.noVerificationCode});
if (!req.body.verificationCode) return res.status(403).json({message: strings.noVerificationCode});

const submittedCode = req.body.verificationCode.trim();
const verificationCode = await VerificationCode.findOne({code: submittedCode});
Expand Down
4 changes: 3 additions & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@
4. Send SMS
- Number: `%RECIPIENT`
- Message: `%DAILYFACT`
5. End For
5. Wait
- Seconds: 2
6. End For
6. Go back to the Profiles tab and create an event based profile for "Recieved Text Any"
7. Create a task for this profile called "CatBot Single"
8. This task will include these actions:
Expand Down
38 changes: 34 additions & 4 deletions public/js/controllers/profile.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* global angular */
var app = angular.module('catfacts');

app.controller('ProfileCtrl', ['$scope', '$rootScope', 'ApiService', function($scope, $rootScope, ApiService) {
app.controller('ProfileCtrl', ['$scope', '$rootScope', 'ApiService', '$state', '$mdDialog', '$mdMedia',
function($scope, $rootScope, ApiService, $state, $mdDialog, $mdMedia) {

$scope.newPhone = $rootScope.authenticatedUser ? $rootScope.authenticatedUser.phone : undefined;

$scope.editField = $scope.editStep = null;

$scope.updatePhone = function(editStep) {
$scope.updatePhone = editStep => {
switch (editStep) {
case null:
$scope.editField = 'phone';
Expand All @@ -19,7 +20,7 @@ app.controller('ProfileCtrl', ['$scope', '$rootScope', 'ApiService', function($s
$scope.editStep = 'verify';
$rootScope.toast({message: "A verification code has been sent to your phone"});
}, err => {
$rootScope.toast({message: err.message || "Couldn't create verification code, try again later."});
$rootScope.toast({message: err.message || "Couldn't create verification code, try again later"});
});
break;

Expand All @@ -31,11 +32,40 @@ app.controller('ProfileCtrl', ['$scope', '$rootScope', 'ApiService', function($s
$scope.newPhone = $scope.verificationCode = '';
$rootScope.toast({message: "New phone number saved"});
}, err => {
$rootScope.toast({message: err.message || "Couldn't update phone number, try again later."});
$rootScope.toast({message: err.message || "Couldn't update phone number, try again later"});
});

break;
}
};

$scope.openDeleteAccountDialog = ev => {
$mdDialog.show({
controller: ['$scope', '$mdDialog', function($scope, $mdDialog) {

$scope.deleteAccount = () => {
ApiService.deleteAccount({verificationEmail: $scope.email}).then(data => {
$rootScope.authenticatedUser = undefined;
$mdDialog.hide(data);
}, err => {
$rootScope.toast({message: err.data.message || "Failed to delete account"});
});
};

$scope.cancel = $mdDialog.cancel;
}],
templateUrl: 'views/partials/delete-account.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: $mdMedia('xs'),
scope: $scope,
preserveScope: true,

}).then(data => {
$rootScope.toast({message: "Your account has been deleted"});
$state.go('facts');
});
};

}]);
4 changes: 4 additions & 0 deletions public/js/services/api.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ app.service('ApiService', ['$rootScope', '$http', '$location', function($rootSco
return $http.get('/users/me');
};

this.deleteAccount = function({verificationEmail}) {
return $http.delete('/users/me', {params: {verificationEmail}});
};

this.updateUserSettings = function(data) {
return $http.put('/users/me/settings', data).then(data => console.log(data), err => console.log(err));
};
Expand Down
25 changes: 25 additions & 0 deletions public/views/partials/delete-account.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<md-dialog flex-gt-xs="40">
<md-dialog-content class="md-dialog-content">
<h2 class="md-title">
Permanently delete your account?
</h2>

<p class="md-subtitle">This action cannot be undone</p>

<md-input-container class="md-block">
<label>Enter your email to confirm</label>
<input type="text" ng-model="email"/>
</md-input-container>
</md-dialog-content>

<md-dialog-actions>
<md-button ng-click="cancel()">Cancel</md-button>
<md-button
ng-click="deleteAccount()"
class="md-warn"
ng-disabled="email != authenticatedUser.email">

Delete
</md-button>
</md-dialog-actions>
</md-dialog>
2 changes: 1 addition & 1 deletion public/views/partials/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ <h3>Delete account</h3>
<p>Remove your account from Cat Facts</p>
</div>

<md-button class="md-secondary md-warn" ng-disabled="true">
<md-button class="md-secondary md-warn" ng-click="openDeleteAccountDialog($event)">
Delete account
</md-button>
</md-list-item>
Expand Down

0 comments on commit 813f401

Please sign in to comment.