소스 검색

Fixed settings.

KrisVos130 8 년 전
부모
커밋
704a0efd1a
2개의 변경된 파일53개의 추가작업 그리고 86개의 파일을 삭제
  1. 43 25
      backend/logic/actions/users.js
  2. 10 61
      frontend/components/User/Settings.vue

+ 43 - 25
backend/logic/actions/users.js

@@ -185,11 +185,12 @@ module.exports = {
 		});
 	},
 
+	//TODO Fix security issues
 	findBySession: (session, cb) => {
 		cache.hget('sessions', session.sessionId, (err, session) => {
 			if (err) return cb({ 'status': 'error', message: err });
 			if (!session) return cb({ 'status': 'error', message: 'You are not logged in' });
-			db.models.user.findOne({ _id: session.userId }, (err, user) => {
+			db.models.user.findOne({ _id: session.userId }, {username: 1, "email.address": 1}, (err, user) => {
 				if (err) { throw err; } else if (user) {
 					return cb({
 						status: 'success',
@@ -201,29 +202,46 @@ module.exports = {
 
 	},
 
-	update: hooks.loginRequired((session, user_id, property, value, cb) => {
-        db.models.user.findOne({ _id: session.userId }, (err, user) => {
-            if (err) throw err;
-            else if (!user) cb({ status: 'error', message: 'Invalid User ID' });
-            else if (user[property] !== undefined && user[property] !== value) {
-                if (property === 'services.password.password') {
-                    bcrypt.compare(user[property], value, (err, res) => {
-                        if (err) throw err;
-                        bcrypt.genSalt(10, (err, salt) => {
-                            if (err) throw err;
-                            bcrypt.hash(value, salt, (err, hash) => {
-                                if (err) throw err;
-                                user[property] = hash;
-                            });
-                        });
-                    });
-                } else user[property] = value;
-                user.save(err => {
-                    if (err) cb({ status: 'error', message: err.message });
-					else cb({ status: 'success', message: 'Field saved successfully' });
-                });
-            } else cb({ status: 'error', message: 'Field has not changed' });
-        });
-    })
+	updateUsername: hooks.loginRequired((session, newUsername, cb, userId) => {
+		db.models.user.findOne({ _id: userId }, (err, user) => {
+			if (err) throw err;
+			if (!user) return cb({ status: 'error', message: 'User not found.' });
+			if (user.username !== newUsername) {
+				if (user.username.toLowerCase() !== newUsername.toLowerCase()) {
+					db.models.user.findOne({username: new RegExp(`^${newUsername}$`, 'i')}, (err, _user) => {
+						if (err) return cb({ status: 'error', message: err.message });
+						if (_user) return cb({ status: 'failure', message: 'That username is already in use.' });
+						db.models.user.update({_id: userId}, {$set: {username: newUsername}}, (err) => {
+							if (err) return cb({ status: 'error', message: err.message });
+							cb({ status: 'success', message: 'Username updated successfully.' });
+						});
+					});
+				} else {
+					db.models.user.update({_id: userId}, {$set: {username: newUsername}}, (err) => {
+						if (err) return cb({ status: 'error', message: err.message });
+						cb({ status: 'success', message: 'Username updated successfully.' });
+					});
+				}
+			} else cb({ status: 'error', message: 'Username has not changed. Your new username cannot be the same as your old username.' });
+		});
+	}),
+
+	updateEmail: hooks.loginRequired((session, newEmail, cb, userId) => {
+		newEmail = newEmail.toLowerCase();
+		db.models.user.findOne({ _id: userId }, (err, user) => {
+			if (err) throw err;
+			if (!user) return cb({ status: 'error', message: 'User not found.' });
+			if (user.email.address !== newEmail) {
+				db.models.user.findOne({"email.address": newEmail}, (err, _user) => {
+					if (err) return cb({ status: 'error', message: err.message });
+					if (_user) return cb({ status: 'failure', message: 'That email is already in use.' });
+					db.models.user.update({_id: userId}, {$set: {"email.address": newEmail}}, (err) => {
+						if (err) return cb({ status: 'error', message: err.message });
+						cb({ status: 'success', message: 'Email updated successfully.' });
+					});
+				});
+			} else cb({ status: 'error', message: 'Email has not changed. Your new email cannot be the same as your old email.' });
+		});
+	})
 
 };

+ 10 - 61
frontend/components/User/Settings.vue

@@ -5,10 +5,8 @@
 		<label class="label">Username</label>
 		<div class="control is-grouped">
 			<p class="control is-expanded has-icon has-icon-right">
-				<input class="input is-success" type="text" placeholder="Change username" v-model="user.username">
+				<input class="input" type="text" placeholder="Change username" v-model="user.username">
 				<!--Remove validation if it's their own without changing-->
-				<i class="fa fa-check"></i>
-				<span class="help is-success">This username is available</span>
 			</p>
 			<p class="control">
 				<button class="button is-success" @click="changeUsername()">Save Changes</button>
@@ -17,33 +15,13 @@
 		<label class="label">Email</label>
 		<div class="control is-grouped">
 			<p class="control is-expanded has-icon has-icon-right">
-				<input class="input is-danger" type="text" placeholder="Change email address" v-model="user.email.address">
+				<input class="input" type="text" placeholder="Change email address" v-model="user.email.address">
 				<!--Remove validation if it's their own without changing-->
-				<i class="fa fa-warning"></i>
-				<span class="help is-danger">This email is invalid</span>
 			</p>
 			<p class="control is-expanded">
 				<button class="button is-success" @click="changeEmail()">Save Changes</button>
 			</p>
 		</div>
-		<label class="label">Change Password</label>
-		<div class="control is-grouped">
-			<p class="control is-expanded has-icon has-icon-right">
-				<input class="input is-danger" type="text" placeholder="Enter current password" v-model="currentPassword">
-				<!-- Check if correct -->
-				<i class="fa fa-warning"></i>
-				<span class="help is-danger">This password is invalid</span>
-			</p>
-			<p class="control is-expanded has-icon has-icon-right">
-				<input class="input is-danger" type="text" placeholder="Enter new password" v-model="newPassword">
-				<!--Check if longer than x chars, has x, x and x. Kris likes x too ;)-->
-				<i class="fa fa-warning"></i>
-				<span class="help is-danger">This password is invalid</span>
-			</p>
-			<p class="control is-expanded">
-				<button class="button is-success" @click="changePassword()">Save Changes</button>
-			</p>
-		</div>
 	</div>
 	<main-footer></main-footer>
 </template>
@@ -59,8 +37,6 @@
 	export default {
 		data() {
 			return {
-				currentPassword: '',
-				newPassword: '',
 				user: {}
 			}
 		},
@@ -80,47 +56,20 @@
 			}, 100);
 		},
 		methods: {
-			changePassword: function () {
-				if (this.currentPassword == "" || this.newPassword == "") return Toast.methods.addToast('Current password field is incorrect', 2000);
-
-				this.socket.emit('users.update', this.user._id, 'services.password.password', this.user.password, res => {
-					if (res.status == 'error') Toast.methods.addToast(res.message, 2000);
-					else Toast.methods.addToast('Successfully changed password', 2000);
-				});
-			},
 			changeEmail: function () {
-				if (this.user.email == "") return Toast.methods.addToast('Field cannot be empty', 2000);
+				if (!this.user.email.address) return Toast.methods.addToast('Email cannot be empty', 8000);
 
-				this.socket.emit('users.update', this.user._id, 'email.address', this.user.email, res => {
-					if (res.status == 'error') Toast.methods.addToast(res.message, 2000);
-					else Toast.methods.addToast('Successfully changed email address', 2000);
+				this.socket.emit('users.updateEmail', this.user.email.address, res => {
+					if (res.status !== 'success') Toast.methods.addToast(res.message, 8000);
+					else Toast.methods.addToast('Successfully changed email address', 4000);
 				});
 			},
-			// Will be added shortly:
-			// changeAvatar() {
-			//     let files = document.getElementById("avatar").files;
-			//     if (files === undefined || files === null) return Materialize.toast(this.getFromLang("error.profilePictureNotSupported"), 4000);
-			//     if (files.length !== 1) return Materialize.toast(this.getFromLang("error.profilePictureOnlyOneFileAllowed"), 4000);
-			//     if (files[0].size >= 2097152) return Materialize.toast(this.getFromLang("error.tooBigProfileImage"), 4000);
-			//     if (files[0].type.indexOf("image/") == -1) return Materialize.toast(this.getFromLang("error.notAnImage"), 4000);
-			//     let local = this;
-			//     fetch(window.location.protocol + '//' + window.location.hostname + ':8081' + '/auth/update/avatar', {
-			//         method: 'POST',
-			//         body: new FormData($('#updateAvatar')[0])
-			//     }).then(response => {
-			//         return response.json()
-			//     }).then(body => {
-			//         if (body.status == 'error') Materialize.toast(body.message, 4000);
-			//         else Materialize.toast(local.getFromLang("settings.profilePictureUpdated"), 4000);
-			//         console.log(body);
-			//     });
-			// },
 			changeUsername: function () {
-				if (this.user.username == "") return Toast.methods.addToast('Field cannot be empty', 2000);
+				if (!this.user.username) return Toast.methods.addToast('Username cannot be empty', 8000);
 
-				this.socket.emit('users.update', this.user._id, 'username', this.user.username, res => {
-					if (res.status == 'error') Toast.methods.addToast(res.message, 2000);
-					else Toast.methods.addToast('Successfully changed username', 2000);
+				this.socket.emit('users.updateUsername', this.user.username, res => {
+					if (res.status !== 'success') Toast.methods.addToast(res.message, 8000);
+					else Toast.methods.addToast('Successfully changed username', 4000);
 				});
 			}
 		},