mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Merge branch '0.4-maintenance'
This commit is contained in:
commit
5491f296ac
4 changed files with 865 additions and 190 deletions
|
@ -5,8 +5,8 @@
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var parseDateFormats = ['DD MMM YY HH:mm', 'DD MMM YYYY HH:mm', 'DD/MM/YY HH:mm', 'DD/MM/YYYY HH:mm',
|
var parseDateFormats = ["DD MMM YY HH:mm", "DD MMM YYYY HH:mm", "DD/MM/YY HH:mm", "DD/MM/YYYY HH:mm",
|
||||||
'DD-MM-YY HH:mm', 'DD-MM-YYYY HH:mm'],
|
"DD-MM-YY HH:mm", "DD-MM-YYYY HH:mm", "YYYY-MM-DD HH:mm"],
|
||||||
displayDateFormat = 'DD MMM YY @ HH:mm';
|
displayDateFormat = 'DD MMM YY @ HH:mm';
|
||||||
|
|
||||||
Ghost.View.PostSettings = Ghost.View.extend({
|
Ghost.View.PostSettings = Ghost.View.extend({
|
||||||
|
@ -158,7 +158,8 @@
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var self = this,
|
var self = this,
|
||||||
errMessage = '',
|
errMessage = '',
|
||||||
pubDate = moment(self.model.get('published_at')).format(displayDateFormat),
|
pubDate = self.model.get('published_at') ? moment(self.model.get('published_at'))
|
||||||
|
.format(displayDateFormat) : '',
|
||||||
pubDateEl = e.currentTarget,
|
pubDateEl = e.currentTarget,
|
||||||
newPubDate = pubDateEl.value,
|
newPubDate = pubDateEl.value,
|
||||||
pubDateMoment,
|
pubDateMoment,
|
||||||
|
|
|
@ -11,7 +11,9 @@ var User,
|
||||||
Role = require('./role').Role,
|
Role = require('./role').Role,
|
||||||
Permission = require('./permission').Permission,
|
Permission = require('./permission').Permission,
|
||||||
http = require('http'),
|
http = require('http'),
|
||||||
crypto = require('crypto');
|
crypto = require('crypto'),
|
||||||
|
|
||||||
|
tokenSecurity = {};
|
||||||
|
|
||||||
function validatePasswordLength(password) {
|
function validatePasswordLength(password) {
|
||||||
try {
|
try {
|
||||||
|
@ -268,6 +270,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
validateToken: function (token, dbHash) {
|
validateToken: function (token, dbHash) {
|
||||||
|
/*jslint bitwise:true*/
|
||||||
// TODO: Is there a chance the use of ascii here will cause problems if oldPassword has weird characters?
|
// TODO: Is there a chance the use of ascii here will cause problems if oldPassword has weird characters?
|
||||||
var tokenText = new Buffer(token, 'base64').toString('ascii'),
|
var tokenText = new Buffer(token, 'base64').toString('ascii'),
|
||||||
parts,
|
parts,
|
||||||
|
@ -288,17 +291,36 @@ User = ghostBookshelf.Model.extend({
|
||||||
return when.reject(new Error("Invalid token expiration"));
|
return when.reject(new Error("Invalid token expiration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is easy to fake, but still check anyway.
|
// Check if token is expired to prevent replay attacks
|
||||||
if (expires < Date.now()) {
|
if (expires < Date.now()) {
|
||||||
return when.reject(new Error("Expired token"));
|
return when.reject(new Error("Expired token"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to prevent brute force attempts to reset the password the combination of email+expires is only allowed for 10 attempts
|
||||||
|
if (tokenSecurity[email + '+' + expires] && tokenSecurity[email + '+' + expires].count >= 10) {
|
||||||
|
return when.reject(new Error("Token locked"));
|
||||||
|
}
|
||||||
|
|
||||||
return this.generateResetToken(email, expires, dbHash).then(function (generatedToken) {
|
return this.generateResetToken(email, expires, dbHash).then(function (generatedToken) {
|
||||||
// Check for matching tokens
|
// Check for matching tokens with timing independent comparison
|
||||||
if (token === generatedToken) {
|
var diff = 0,
|
||||||
|
i;
|
||||||
|
|
||||||
|
// check if the token lenght is correct
|
||||||
|
if (token.length !== generatedToken.length) {
|
||||||
|
diff = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = token.length - 1; i >= 0; i = i - 1) {
|
||||||
|
diff |= token.charCodeAt(i) ^ generatedToken.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff === 0) {
|
||||||
return when.resolve(email);
|
return when.resolve(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// increase the count for email+expires for each failed attempt
|
||||||
|
tokenSecurity[email + '+' + expires] = {count: tokenSecurity[email + '+' + expires] ? tokenSecurity[email + '+' + expires].count + 1 : 1};
|
||||||
return when.reject(new Error("Invalid token"));
|
return when.reject(new Error("Invalid token"));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
1016
core/shared/vendor/moment.js
vendored
1016
core/shared/vendor/moment.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name" : "ghost",
|
"name" : "ghost",
|
||||||
"version" : "0.4.1-rc1",
|
"version" : "0.4.1",
|
||||||
"description" : "Just a blogging platform.",
|
"description" : "Just a blogging platform.",
|
||||||
"author" : "Ghost Foundation",
|
"author" : "Ghost Foundation",
|
||||||
"homepage" : "http://ghost.org",
|
"homepage" : "http://ghost.org",
|
||||||
|
|
Loading…
Add table
Reference in a new issue