diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2017-12-14 19:53:31 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2017-12-14 19:53:31 +0100 |
| commit | 3a42fe7ad797a6f9cf747d2d358015ac992765a7 (patch) | |
| tree | 169c2123067abc677b9e3fa8d19142bd3af3338e | |
| parent | d776e6aa7d1e458ef050c016a4c285aa5887c5f0 (diff) | |
change password - profile stuff
| -rw-r--r-- | bucky-schema.sql | 5 | ||||
| -rw-r--r-- | bucky/app/bucky.js | 38 | ||||
| -rw-r--r-- | bucky/app/index.js | 14 | ||||
| -rw-r--r-- | bucky/app/router.js | 6 | ||||
| -rw-r--r-- | bucky/util/auth.js | 16 | ||||
| -rw-r--r-- | bucky/util/upload.js | 7 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 9 | ||||
| -rw-r--r-- | public/assets/js/lib/sdk/auth.js | 7 | ||||
| -rw-r--r-- | public/assets/js/lib/views/index/hootbox.js | 2 | ||||
| -rw-r--r-- | public/assets/js/lib/views/profile/profile_edit.js | 16 | ||||
| -rw-r--r-- | public/assets/js/vendor/dataUriToBlob.js | 58 | ||||
| -rw-r--r-- | public/assets/js/vendor/view/formview.js | 96 | ||||
| -rw-r--r-- | views/pages/login.ejs | 2 | ||||
| -rw-r--r-- | views/pages/profile_form.ejs | 6 | ||||
| -rw-r--r-- | views/pages/signup.ejs | 2 | ||||
| -rw-r--r-- | views/partials/scripts.ejs | 1 |
16 files changed, 189 insertions, 96 deletions
diff --git a/bucky-schema.sql b/bucky-schema.sql index 9d68811..b6ec8d6 100644 --- a/bucky-schema.sql +++ b/bucky-schema.sql @@ -187,10 +187,9 @@ CREATE TABLE `users` ( `firstseen` int(11) DEFAULT NULL, `lastseen` int(11) DEFAULT NULL, `phone` varchar(64) DEFAULT NULL, - `webpage` varchar(255) DEFAULT NULL, `location` varchar(64) DEFAULT NULL, - `fb` varchar(255) DEFAULT NULL, - `tw` varchar(255) DEFAULT NULL, + `twitter` varchar(255) DEFAULT NULL, + `website` varchar(255) DEFAULT NULL, `avatar` varchar(255) DEFAULT NULL, `keywords` varchar(512) DEFAULT '', `stickies` varchar(512) DEFAULT '', diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js index 7dac066..cf74ec2 100644 --- a/bucky/app/bucky.js +++ b/bucky/app/bucky.js @@ -384,6 +384,7 @@ var bucky = module.exports = { } db.getUserByUsername(username).then(function(user){ if (user) { + res.user = user next() } else { @@ -402,43 +403,24 @@ var bucky = module.exports = { 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]) + 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) { + if (! req.file) return next() + var dirname = '/bucky/profile/' upload.put({ - file: file, - preserveFilename: true, + file: req.file, + filename: req.user.get('username') + '.jpg', dirname: dirname, unacceptable: function(err){ - reject(err) + res.sendStatus({ error: 'Problem uploading avatar.' }) }, 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) ) + console.log(">", url) + res.user.set('avatar', url) + next() } }) }, diff --git a/bucky/app/index.js b/bucky/app/index.js index 248679a..b600935 100644 --- a/bucky/app/index.js +++ b/bucky/app/index.js @@ -25,12 +25,16 @@ site.init = function(){ app.set('port', process.env.PORT || 5000) app.use(favicon(__dirname + '../../../public/favicon.ico')) app.use(bodyParser.json()) - app.use(cookieParser()); + app.use(cookieParser()) app.use(session({ secret: 'argonauts', proxy: true, key: 'bucky.sid', - cookie: {secure: true, domain: '.' + process.env.HOST_NAME, maxAge: 43200000000 }, + cookie: { + secure: process.env.NODE_ENV === 'production', + domain: '.' + process.env.HOST_NAME, + maxAge: 43200000000, + }, store: new MongoStore({ url: 'mongodb://localhost/buckySessionDb' // type: 'mongodb', @@ -43,7 +47,11 @@ site.init = function(){ resave: true, saveUninitialized: false, })) - app.use(csurf({ cookie: true })) + + app.use(csurf({ + cookie: true, + value: (req) => req.headers['csrf-token'], + })) app.disable('x-powered-by') app.use(express.query()) diff --git a/bucky/app/router.js b/bucky/app/router.js index dfec166..7e13cd6 100644 --- a/bucky/app/router.js +++ b/bucky/app/router.js @@ -1,3 +1,4 @@ +var multer = require('multer')() var auth = require('../util/auth') var middleware = require('../util/middleware') var fortune = require('../db/fortune') @@ -5,7 +6,6 @@ var bucky = require('./bucky') var db = require('../db') var util = require('../util/util') var search = require('../search/middleware') -var multer = require('multer')() module.exports = function(app){ app.all('*', middleware.ensureLocals) @@ -84,11 +84,11 @@ module.exports = function(app){ bucky.checkUserPrivacy, multer.single("avatar"), bucky.updateProfile, - bucky.changePassword, + auth.changePassword, bucky.uploadAvatar, bucky.saveUser, function(req, res){ - res.json(res.thread) + res.json(util.sanitizeUser(res.user)) }) /* threads */ diff --git a/bucky/util/auth.js b/bucky/util/auth.js index 3cc01f0..4556733 100644 --- a/bucky/util/auth.js +++ b/bucky/util/auth.js @@ -125,6 +125,20 @@ var auth = module.exports = { return user.get('password') === auth.makePassword(user.get('username'), pw); }, + 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 username = req.user.get('username') + var newPassword = auth.makePassword(username, req.body.newpassword) + res.user.set('password', newPassword) + next() + }, + verifyLocalUser: function (username, password, done) { // handle passwords!! db.getUserByUsername(username).then(function(user){ @@ -143,7 +157,7 @@ var auth = module.exports = { checkin: function (req, res) { var user = util.sanitizeUser(req.user) - res.json(user) + res.json({ user: user }) }, logout: function (req, res) { diff --git a/bucky/util/upload.js b/bucky/util/upload.js index d7bf822..5bc8190 100644 --- a/bucky/util/upload.js +++ b/bucky/util/upload.js @@ -35,10 +35,11 @@ module.exports.put = function (opt) { var types = opt.types var extension = types && types[file.mimetype] - if (opt.preserveFilename) { + if (opt.filename) { + filename = opt.filename + } else if (opt.preserveFilename) { filename = file.originalname - } - else { + } else { filename = uuid.v1() + "." + extension; } diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index aaab3f9..c4792af 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -882,6 +882,15 @@ header .search_form { margin-top: 12px; display: none; } +#profile_form #profile-avatar-embed { + max-width: 250px; + display: block; + margin-bottom: 5px; +} +.save_field a { + margin-top: 7px; + margin-left: 7px; +} /* 404 */ #error_404 { diff --git a/public/assets/js/lib/sdk/auth.js b/public/assets/js/lib/sdk/auth.js index c720292..0b49449 100644 --- a/public/assets/js/lib/sdk/auth.js +++ b/public/assets/js/lib/sdk/auth.js @@ -70,6 +70,7 @@ var auth = (function(){ $.ajax({ method: 'put', url: '/api/checkin', + headers: { "csrf-token": $("[name=_csrf]").attr("value") }, success: function(data){ if (data && data.user && data.user.id !== -1) { auth.set_user(data.user) @@ -77,7 +78,11 @@ var auth = (function(){ return } opt.error() - } + }, + error: function(){ + window.location.href = '/login' + opt.error() + }, }) } diff --git a/public/assets/js/lib/views/index/hootbox.js b/public/assets/js/lib/views/index/hootbox.js index 85fd51e..2338153 100644 --- a/public/assets/js/lib/views/index/hootbox.js +++ b/public/assets/js/lib/views/index/hootbox.js @@ -23,7 +23,7 @@ var HootBox = FormView.extend({ }, parse: function(comment){ - var t = this.template.replace(/{{username}}/g, profile_image(comment.username)) + var t = this.template.replace(/{{image}}/g, profile_image(comment.username)) .replace(/{{username}}/g, comment.username) .replace(/{{comment}}/g, tidy_urls(comment.comment, true)) return t diff --git a/public/assets/js/lib/views/profile/profile_edit.js b/public/assets/js/lib/views/profile/profile_edit.js index a887357..e50a7c0 100644 --- a/public/assets/js/lib/views/profile/profile_edit.js +++ b/public/assets/js/lib/views/profile/profile_edit.js @@ -64,6 +64,7 @@ var ProfileForm = FormView.extend({ canvas.height = h ctx.drawImage(img, 0, 0, w, h) var dataURI = canvas.toDataURL('image/jpeg', 0.85) + this.avatarBlob = dataUriToBlob(dataURI) this.$("#profile-avatar-embed").show().attr("src", dataURI).css("width", w/2) }, @@ -71,6 +72,18 @@ var ProfileForm = FormView.extend({ this.$(".oldpassword").css('display', 'flex') }, + serialize: function(){ + var fd = this.__super__.serialize.call(this) + var oldpw = this.$("[name=oldpassword]").val() + var pw = this.$("[name=newpassword]").val() + var pw2 = this.$("[name=newpassword2]").val() + fd.delete('avatar') + if (this.avatarBlob) { + fd.append("avatar", this.avatarBlob) + } + return fd + }, + validate: function(){ var errors = [] var oldpw = this.$("[name=oldpassword]").val() @@ -89,6 +102,7 @@ var ProfileForm = FormView.extend({ if (data.error) { return alert(data.error) } - window.location.href = "/details/" + data.id + auth.set_user(data.user) + window.location.href = "/profile" } })
\ No newline at end of file diff --git a/public/assets/js/vendor/dataUriToBlob.js b/public/assets/js/vendor/dataUriToBlob.js new file mode 100644 index 0000000..80189b8 --- /dev/null +++ b/public/assets/js/vendor/dataUriToBlob.js @@ -0,0 +1,58 @@ +var dataUriToUint8Array = function(uri){ + var data = uri.split(',')[1]; + var bytes = atob(data); + var buf = new ArrayBuffer(bytes.length); + var u8 = new Uint8Array(buf); + for (var i = 0; i < bytes.length; i++) { + u8[i] = bytes.charCodeAt(i); + } + return u8 +} + +window.dataUriToBlob = (function(){ +/** + * Blob constructor. + */ + +var Blob = window.Blob; + +/** + * ArrayBufferView support. + */ + +var hasArrayBufferView = new Blob([new Uint8Array(100)]).size == 100; + +/** + * Return a `Blob` for the given data `uri`. + * + * @param {String} uri + * @return {Blob} + * @api public + */ + +var dataUriToBlob = function(uri){ + var data = uri.split(',')[1]; + var bytes = atob(data); + var buf = new ArrayBuffer(bytes.length); + var arr = new Uint8Array(buf); + for (var i = 0; i < bytes.length; i++) { + arr[i] = bytes.charCodeAt(i); + } + + if (!hasArrayBufferView) arr = buf; + var blob = new Blob([arr], { type: mime(uri) }); + blob.slice = blob.slice || blob.webkitSlice; + return blob; +}; + +/** + * Return data uri mime type. + */ + +function mime(uri) { + return uri.split(';')[0].slice(5); +} + +return dataUriToBlob; + +})() diff --git a/public/assets/js/vendor/view/formview.js b/public/assets/js/vendor/view/formview.js index 6b03849..923e212 100644 --- a/public/assets/js/vendor/view/formview.js +++ b/public/assets/js/vendor/view/formview.js @@ -90,44 +90,28 @@ var FormView = View.extend({ var action = typeof this.action == "function" ? this.action() : this.action if (! action) return - var data = this.serialize() - var request = $.ajax({ - url: action, - type: this.method, - data: data, - headers: { "csrf-token": $("[name=_csrf]").attr("value") }, - contentType: data instanceof FormData ? false : "application/json", - dataType: "json", - processData: false, - success: function(response){ - if (response.error) { - var errors = [] - if (response.error.errors) { - for (var key in response.error.errors) { - errors.push(response.error.errors[key].message); - } - } else { - errors.push(response.error) - } - if (errorCallback) { - errorCallback(errors) - } - else { - this.showErrors(errors) - } - return - } - if (successCallback) { - successCallback(response) - } - if (this.success) { - this.success(response) - } - }.bind(this), - error: function(response){ + var data = this.serialize() + var headers = new Headers() + headers.append("csrf-token", $("[name=_csrf]").attr("value")) + if (typeof data === "string") { + headers.append("content-type", "application/json") + } + + fetch(action, { + method: this.method.toUpperCase(), + headers: headers, + credentials: 'same-origin', + body: data, + }).then(raw => raw.json()) + .then(response => { + if (response.error) { var errors = [] - for (var key in response.error.errors) { - errors.push(response.error.errors[key].message); + if (response.error.errors) { + for (var key in response.error.errors) { + errors.push(response.error.errors[key].message); + } + } else { + errors.push(response.error) } if (errorCallback) { errorCallback(errors) @@ -135,17 +119,35 @@ var FormView = View.extend({ else { this.showErrors(errors) } - }.bind(this), - complete: function(response){ - if (this.useMinotaur) { - Minotaur.hide() - } - }.bind(this), + return + } + if (successCallback) { + successCallback(response) + } + if (this.success) { + this.success(response) + } + }).catch(response => { + var errors = [] + for (var key in response.error.errors) { + errors.push(response.error.errors[key].message); + } + if (errorCallback) { + errorCallback(errors) + } + else { + this.showErrors(errors) + } }) - - if (this.useMinotaur) { - Minotaur.show() - } +// complete: function(response){ +// if (this.useMinotaur) { +// Minotaur.hide() +// } +// } +// +// if (this.useMinotaur) { +// Minotaur.show() +// } this.beforeSend && this.beforeSend() }, diff --git a/views/pages/login.ejs b/views/pages/login.ejs index 82842df..f2b686a 100644 --- a/views/pages/login.ejs +++ b/views/pages/login.ejs @@ -12,7 +12,7 @@ <input type="password" id="login-password" name="password"> </div> - <div> + <div class="save_field"> <label for="login-submit"></label> <button id="login-submit">LOGIN</button> <a href="/signup">Signup</a> diff --git a/views/pages/profile_form.ejs b/views/pages/profile_form.ejs index 31ad7e0..4606ce4 100644 --- a/views/pages/profile_form.ejs +++ b/views/pages/profile_form.ejs @@ -39,8 +39,8 @@ <br> <div> - <label for="profile-webpage">Website</label> - <input type="text" id="profile-webpage" name="webpage"> + <label for="profile-website">Website</label> + <input type="text" id="profile-webpage" name="website"> </div> <!-- @@ -72,7 +72,7 @@ </div> <br> - <div> + <div class="save_field"> <label for="profile-submit"></label> <button id="profile-submit">SAVE PROFILE</button> </div> diff --git a/views/pages/signup.ejs b/views/pages/signup.ejs index c13fc33..65a29cf 100644 --- a/views/pages/signup.ejs +++ b/views/pages/signup.ejs @@ -30,7 +30,7 @@ <input type="text" id="login-grass" name="grass"> </div> - <div> + <div class="save_field"> <label for="login-submit"></label> <button id="login-submit">SIGNUP</button> <a href="/login">Login</a> diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index e80bdda..83845ee 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -4,6 +4,7 @@ <script src="/assets/js/vendor/parser.js"></script> <script src="/assets/js/vendor/sha1.js"></script> <script src="/assets/js/vendor/util.js"></script> +<script src="/assets/js/vendor/dataUriToBlob.js"></script> <script src="/assets/js/vendor/view/view.js"></script> <script src="/assets/js/vendor/view/formview.js"></script> <script src="/assets/js/vendor/view/router.js"></script> |
