소스 검색

Fixed issues with password login cookies and added change password.

KrisVos130 8 년 전
부모
커밋
3a49b89fd8
3개의 변경된 파일77개의 추가작업 그리고 5개의 파일을 삭제
  1. 54 2
      backend/logic/actions/users.js
  2. 4 2
      frontend/App.vue
  3. 19 1
      frontend/components/User/Settings.vue

+ 54 - 2
backend/logic/actions/users.js

@@ -255,15 +255,22 @@ module.exports = {
 				logger.error("FIND_BY_SESSION", "Session not found. Not logged in.");
 				return cb({ 'status': 'error', message: 'You are not logged in' });
 			}
-			db.models.user.findOne({ _id: session.userId }, {username: 1, "email.address": 1}, (err, user) => {
+			db.models.user.findOne({ _id: session.userId }, (err, user) => {
 				if (err) {
 					logger.error("FIND_BY_SESSION", "User not found. Failed getting user. Mongo error.");
 					throw err;
 				} else if (user) {
+					let userObj = {
+						email: {
+							address: user.email.address
+						},
+						username: user.username
+					};
+					if (user.services.password && user.services.password.password) userObj.password = true;
 					logger.success("FIND_BY_SESSION", "User found. '" + user.username + "'.");
 					return cb({
 						status: 'success',
-						data: user
+						data: userObj
 					});
 				}
 			});
@@ -399,5 +406,50 @@ module.exports = {
 				message: 'Role successfully updated.'
 			});
 		});
+	}),
+
+	/**
+	 * Updates a user's password
+	 *
+	 * @param {Object} session - the session object automatically added by socket.io
+	 * @param {String} newPassword - the new password
+	 * @param {Function} cb - gets called with the result
+	 * @param {String} userId - the userId automatically added by hooks
+	 */
+	updatePassword: hooks.loginRequired((session, newPassword, cb, userId) => {
+		async.waterfall([
+			(next) => {
+				db.models.user.findOne({_id: userId}, next);
+			},
+
+			(user, next) => {
+				if (!user.services.password) return next('This account does not have a password set.');
+				next();
+			},
+
+			(next) => {
+				bcrypt.genSalt(10, next);
+			},
+
+			// hash the password
+			(salt, next) => {
+				bcrypt.hash(sha256(newPassword), salt, next);
+			},
+
+			(hashedPassword, next) => {
+				db.models.user.update({_id: userId}, {$set: {"services.password.password": hashedPassword}}, next);
+			}
+		], (err) => {
+			if (err) {
+				logger.error("UPDATE_PASSWORD", `Failed updating user. Mongo error. '${err.message}'.`);
+				return cb({ status: 'error', message: 'Something went wrong.' });
+			}
+
+			logger.error("UPDATE_PASSWORD", `User '${userId}' updated their password.`);
+			cb({
+				status: 'success',
+				message: 'Password successfully updated.'
+			});
+		});
 	})
 };

+ 4 - 2
frontend/App.vue

@@ -95,7 +95,8 @@
 								lofig.get('cookie', cookie => {
 									let date = new Date();
 									date.setTime(new Date().getTime() + (2 * 365 * 24 * 60 * 60 * 1000));
-									document.cookie = `SID=${result.SID}; expires=${date.toGMTString()}; domain=${cookie.domain}; secure=${cookie.secure}; path=/`;
+									let secure = (cookie.secure) ? 'secure=true; ' : '';
+									document.cookie = `SID=${result.SID}; expires=${date.toGMTString()}; domain=${cookie.domain}; ${secure}path=/`;
 									location.reload();
 								});
 							} else _this.$router.go('/login');
@@ -111,7 +112,8 @@
 						lofig.get('cookie', cookie => {
 							let date = new Date();
 							date.setTime(new Date().getTime() + (2 * 365 * 24 * 60 * 60 * 1000));
-							document.cookie = `SID=${result.SID}; expires=${date.toGMTString()}; domain=${cookie.domain}; secure=${cookie.secure}; path=/`;
+							let secure = (cookie.secure) ? 'secure=true; ' : '';
+							document.cookie = `SID=${result.SID}; expires=${date.toGMTString()}; domain=${cookie.domain}; ${secure}path=/`;
 							Toast.methods.addToast(`You have been successfully logged in`, 2000);
 							_this.$router.go('/');
 							location.reload();

+ 19 - 1
frontend/components/User/Settings.vue

@@ -22,6 +22,15 @@
 				<button class="button is-success" @click="changeEmail()">Save Changes</button>
 			</p>
 		</div>
+		<label class="label" v-if="user.password">Change Password</label>
+		<div class="control is-grouped" v-if="user.password">
+			<p class="control is-expanded has-icon has-icon-right">
+				<input class="input" type="password" placeholder="Change password" v-model="newPassword">
+			</p>
+			<p class="control is-expanded">
+				<button class="button is-success" @click="changePassword()">Change password</button>
+			</p>
+		</div>
 	</div>
 	<main-footer></main-footer>
 </template>
@@ -38,7 +47,8 @@
 	export default {
 		data() {
 			return {
-				user: {}
+				user: {},
+				newPassword: ''
 			}
 		},
 		ready: function() {
@@ -71,6 +81,14 @@
 					if (res.status !== 'success') Toast.methods.addToast(res.message, 8000);
 					else Toast.methods.addToast('Successfully changed username', 4000);
 				});
+			},
+			changePassword: function () {
+				let _this = this;
+				if (!_this.newPassword) return Toast.methods.addToast('New password cannot be empty', 8000);
+				_this.socket.emit('users.updatePassword', _this.newPassword, res => {
+					if (res.status !== 'success') Toast.methods.addToast(res.message, 8000);
+					else Toast.methods.addToast('Successfully changed password', 4000);
+				});
 			}
 		},
 		components: { MainHeader, MainFooter, LoginModal }