diff options
| -rw-r--r-- | bucky-schema.sql | 1 | ||||
| -rw-r--r-- | bucky/app/bucky.js | 52 | ||||
| -rw-r--r-- | bucky/app/router.js | 6 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 7 | ||||
| -rw-r--r-- | public/assets/js/lib/views/profile/profile_edit.js | 66 | ||||
| -rw-r--r-- | views/pages/profile_form.ejs | 21 |
6 files changed, 131 insertions, 22 deletions
diff --git a/bucky-schema.sql b/bucky-schema.sql index 8f5c347..9d68811 100644 --- a/bucky-schema.sql +++ b/bucky-schema.sql @@ -191,6 +191,7 @@ CREATE TABLE `users` ( `location` varchar(64) DEFAULT NULL, `fb` varchar(255) DEFAULT NULL, `tw` varchar(255) DEFAULT NULL, + `avatar` varchar(255) DEFAULT NULL, `keywords` varchar(512) DEFAULT '', `stickies` varchar(512) DEFAULT '', `settings` varchar(512) DEFAULT '', diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js index f3ea689..7dac066 100644 --- a/bucky/app/bucky.js +++ b/bucky/app/bucky.js @@ -384,7 +384,6 @@ var bucky = module.exports = { } db.getUserByUsername(username).then(function(user){ if (user) { - res.user = util.sanitizeUser(user) next() } else { @@ -392,12 +391,59 @@ var bucky = module.exports = { } }) }, + sanitizeUser: function(req, res, next) { + res.user = util.sanitizeUser(res.user) + next() + }, bumpLastSeen: function(req, res, next) { req.user.set('lastseen', util.now()) req.user.save().then( () => next() ) }, - updateUser: function(req, res, next) { - + updateProfile: function(req, res, next) { + var user = res.user + "realname location email phone website twitter".split(" ").forEach( (field) => { + res.user.set("field", req.body[field]) + }) + next() + }, + changePassword: function(req, res, next) { + if (! req.body.oldpassword && ! req.body.newpassword) return next() + if (req.body.newpassword !== req.body.newpassword2) { + return res.send({ error: 'Passwords don\'t match.' }) + } + if (! auth.validPassword(res.user, req.body.oldpassword)) { + return res.send({ error: 'Password is incorrect.' }) + } + var newPassword = auth.makePassword(res.user, req.body.newpassword) + res.user.set('password', newPassword) + next() + }, + uploadAvatar: function(req, res, next) { + upload.put({ + file: file, + preserveFilename: true, + dirname: dirname, + unacceptable: function(err){ + reject(err) + }, + success: function(url){ + var data = { + thread: res.thread.get('id'), + username: req.user.get('username'), + filename: file.originalname, + date: util.now(), + size: file.size, + private: false, + storage: 'i.asdf.us', + } + db.createFile(data).then(function(file){ + resolve(file) + }).catch( (err) => reject(err) ) + } + }) + }, + saveUser: function(req, res, next){ + res.user.save().then( () => next() ) }, /* PRIVACY */ diff --git a/bucky/app/router.js b/bucky/app/router.js index 0935f1a..dfec166 100644 --- a/bucky/app/router.js +++ b/bucky/app/router.js @@ -73,6 +73,7 @@ module.exports = function(app){ app.get("/api/user/:username", middleware.ensureAuthenticated, bucky.ensureUser, + bucky.sanitizeUser, function(req, res) { res.json(res.user) } @@ -82,7 +83,10 @@ module.exports = function(app){ bucky.ensureUser, bucky.checkUserPrivacy, multer.single("avatar"), - bucky.updateUser, + bucky.updateProfile, + bucky.changePassword, + bucky.uploadAvatar, + bucky.saveUser, function(req, res){ res.json(res.thread) }) diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index a85ac21..aaab3f9 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -875,6 +875,13 @@ header .search_form { margin-bottom: 5px; max-width: 100px; } +#profile_form input[type=text] { + width: 200px; +} +#profile_form form > div.oldpassword { + margin-top: 12px; + display: none; +} /* 404 */ #error_404 { diff --git a/public/assets/js/lib/views/profile/profile_edit.js b/public/assets/js/lib/views/profile/profile_edit.js index a6ff211..a887357 100644 --- a/public/assets/js/lib/views/profile/profile_edit.js +++ b/public/assets/js/lib/views/profile/profile_edit.js @@ -3,7 +3,8 @@ var ProfileForm = FormView.extend({ el: "#profile_form", events: { - "change #profile-pic": 'changeProfilePic', + "input #profile-newpassword": 'showOldPassword', + "change #profile-avatar": 'changeAvatar', }, action: "/api/user", @@ -15,28 +16,71 @@ var ProfileForm = FormView.extend({ }, load: function(username){ - console.log('hi') this.action = "/api/user/" + username; - "realname location email phone website fb twitter".split(" ").forEach((field) => { + "realname location email phone website twitter".split(" ").forEach((field) => { this.$('[name=' + field + ']').val( sanitize(auth.user[field]) ) }) - if (! auth.user.pic) { - $("#profile-pic-embed").hide() + if (! auth.user.avatar) { + $("#profile-avatar-embed").hide() } else { - $("#profile-pic-embed").attr("src", sanitize(auth.user.pic)) + $("#profile-avatar-embed").attr("src", sanitize(auth.user.avatar)) } $("body").removeClass('loading') }, - changeProfilePic: function(){ - // $("#profile-pic-embed").show().attr("src", sanitize(auth.user.pic)) + changeAvatar: function(e){ + var files = e.dataTransfer ? e.dataTransfer.files : e.target.files; + if (! files.length) return + var f = files[0] + if ( ! f.type.match('image.*')) { + e.preventDefault() + return; + } + var reader = new FileReader(); + reader.onload = (e) => { + var img = new Image() + img.onload = () => { + this.showAvatar(img) + } + img.src = e.target.result + } + reader.readAsDataURL(f); + }, + + showAvatar: function(img){ + var canvas = document.createElement("canvas") + var ctx = canvas.getContext('2d') + var w, h + var ratio = img.naturalWidth / img.naturalHeight + if (ratio > 1) { // landscape + w = 500 + h = 500 / ratio + } + else { + h = 500 + w = 500 * ratio + } + canvas.width = w + canvas.height = h + ctx.drawImage(img, 0, 0, w, h) + var dataURI = canvas.toDataURL('image/jpeg', 0.85) + this.$("#profile-avatar-embed").show().attr("src", dataURI).css("width", w/2) + }, + + showOldPassword: function(){ + this.$(".oldpassword").css('display', 'flex') }, validate: function(){ var errors = [] - var title = this.$("[name=title]").val() - if (! title || ! title.length) { - errors.push("Please title your post.") + var oldpw = this.$("[name=oldpassword]").val() + var pw = this.$("[name=newpassword]").val() + var pw2 = this.$("[name=newpassword2]").val() + if (pw !== pw2) { + errors.push("Passwords don't match.") + } + if (pw && ! oldpw) { + errors.push("Please enter your old password.") } return errors.length ? errors : null }, diff --git a/views/pages/profile_form.ejs b/views/pages/profile_form.ejs index 01b0fae..31ad7e0 100644 --- a/views/pages/profile_form.ejs +++ b/views/pages/profile_form.ejs @@ -30,10 +30,10 @@ <br> <div> - <label for="profile-pic">Profile picture</label> + <label for="profile-avatar">Profile picture</label> <div> - <img id="profile-pic-embed" /> - <input type="file" id="profile-pic" name="pic"> + <img id="profile-avatar-embed" /> + <input type="file" id="profile-avatar" name="avatar" accept="image/*"> </div> </div> <br> @@ -43,10 +43,12 @@ <input type="text" id="profile-webpage" name="webpage"> </div> +<!-- <div> <label for="profile-fb">Facebook</label> <input type="text" id="profile-fb" name="fb"> </div> + --> <div> <label for="profile-tw">Twitter</label> @@ -55,13 +57,18 @@ <br> <div> - <label for="profile-password">Change password?</label> - <input type="password" id="profile-password" name="password"> + <label for="profile-newpassword">Change password?</label> + <input type="password" id="profile-newpassword" name="newpassword"> </div> <div> - <label for="profile-password2">again:</label> - <input type="password" id="profile-password2" name="password2"> + <label for="profile-newpassword2">again:</label> + <input type="password" id="profile-newpassword2" name="newpassword2"> + </div> + + <div class="oldpassword"> + <label for="profile-oldpassword"><i>yr old password:</i></label> + <input type="password" id="profile-oldpassword" name="oldpassword"> </div> <br> |
