summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bucky-schema.sql1
-rw-r--r--bucky/app/bucky.js52
-rw-r--r--bucky/app/router.js6
-rw-r--r--public/assets/css/bucky.css7
-rw-r--r--public/assets/js/lib/views/profile/profile_edit.js66
-rw-r--r--views/pages/profile_form.ejs21
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>