Enforce HTTPS for new profile images
This commit is contained in:
parent
53d385f53e
commit
8719527a31
|
@ -13,6 +13,7 @@ var Config = require("../config");
|
||||||
var Server = require("../server");
|
var Server = require("../server");
|
||||||
var session = require("../session");
|
var session = require("../session");
|
||||||
var csrf = require("./csrf");
|
var csrf = require("./csrf");
|
||||||
|
const url = require("url");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a GET request for /account/edit
|
* Handles a GET request for /account/edit
|
||||||
|
@ -396,6 +397,25 @@ function handleAccountProfilePage(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateProfileImage(image, callback) {
|
||||||
|
var prefix = "Invalid URL for profile image: ";
|
||||||
|
var link = image.trim();
|
||||||
|
if (!link) {
|
||||||
|
process.nextTick(callback, null, link);
|
||||||
|
} else {
|
||||||
|
var data = url.parse(link);
|
||||||
|
if (!data.protocol || data.protocol !== 'https:') {
|
||||||
|
process.nextTick(callback,
|
||||||
|
new Error(prefix + " URL must begin with 'https://'"));
|
||||||
|
} else if (!data.host) {
|
||||||
|
process.nextTick(callback,
|
||||||
|
new Error(prefix + "missing hostname"));
|
||||||
|
} else {
|
||||||
|
process.nextTick(callback, null, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to edit a profile
|
* Handles a POST request to edit a profile
|
||||||
*/
|
*/
|
||||||
|
@ -410,23 +430,37 @@ function handleAccountProfile(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var image = req.body.image;
|
var rawImage = String(req.body.image).substring(0, 255);
|
||||||
var text = req.body.text;
|
var text = String(req.body.text).substring(0, 255);
|
||||||
|
|
||||||
db.users.setProfile(req.user.name, { image: image, text: text }, function (err) {
|
validateProfileImage(rawImage, (error, image) => {
|
||||||
if (err) {
|
if (error) {
|
||||||
sendPug(res, "account-profile", {
|
db.users.getProfile(req.user.name, function (err, profile) {
|
||||||
profileImage: "",
|
var errorMessage = err || error.message;
|
||||||
profileText: "",
|
sendPug(res, "account-profile", {
|
||||||
profileError: err
|
profileImage: profile ? profile.image : "",
|
||||||
|
profileText: profile ? profile.text : "",
|
||||||
|
profileError: errorMessage
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPug(res, "account-profile", {
|
db.users.setProfile(req.user.name, { image: image, text: text }, function (err) {
|
||||||
profileImage: image,
|
if (err) {
|
||||||
profileText: text,
|
sendPug(res, "account-profile", {
|
||||||
profileError: false
|
profileImage: "",
|
||||||
|
profileText: "",
|
||||||
|
profileError: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPug(res, "account-profile", {
|
||||||
|
profileImage: image,
|
||||||
|
profileText: text,
|
||||||
|
profileError: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,42 @@ html(lang="en")
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for="profileimage") Image
|
label.control-label(for="profileimage") Image
|
||||||
input#profileimage.form-control(type="text", name="image")
|
input#profileimage.form-control(type="text", name="image", maxlength="255")
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for="profiletext") Text
|
label.control-label(for="profiletext") Text
|
||||||
textarea#profiletext.form-control(cols="10", name="text")= profileText
|
textarea#profiletext.form-control(cols="10", name="text", maxlength="255")= profileText
|
||||||
button.btn.btn-primary.btn-block(type="submit") Save
|
button.btn.btn-primary.btn-block(type="submit") Save
|
||||||
|
|
||||||
include footer
|
include footer
|
||||||
+footer()
|
+footer()
|
||||||
script(type="text/javascript").
|
script(type="text/javascript").
|
||||||
$("#profileimage").val("#{profileImage}");
|
var $profileImage = $("#profileimage");
|
||||||
|
$profileImage.val("#{profileImage}");
|
||||||
|
var hasError = false;
|
||||||
|
function validateImage() {
|
||||||
|
var value = $profileImage.val().trim();
|
||||||
|
$profileImage.val(value);
|
||||||
|
if (!/^$|^https:/.test(value)) {
|
||||||
|
hasError = true;
|
||||||
|
$profileImage.parent().addClass("has-error");
|
||||||
|
var $error = $("#profileimage-error");
|
||||||
|
if ($error.length === 0) {
|
||||||
|
$error = $("<p/>")
|
||||||
|
.attr({ id: "profileimage-error" })
|
||||||
|
.addClass("text-danger")
|
||||||
|
.html("Profile image must be a URL beginning with <code>https://</code>")
|
||||||
|
.insertAfter($profileImage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasError = false;
|
||||||
|
$profileImage.parent().removeClass("has-error");
|
||||||
|
$("#profileimage-error").remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("form").submit(function (event) {
|
||||||
|
validateImage();
|
||||||
|
if (hasError) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue