0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Merge branch '0.3.2-wip'

Conflicts:
	core/client/assets/lib/uploader.js
This commit is contained in:
Hannah Wolfe 2013-10-11 20:56:15 +01:00
commit 119b0ea430
11 changed files with 192 additions and 46 deletions

View file

@ -1,24 +0,0 @@
#ignore database
b-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
.idea/*
*.iml
projectFilesBackup
.DS_Store
# Ghost DB file
*.db

5
.gitignore vendored
View file

@ -38,7 +38,12 @@ projectFilesBackup
/core/server/data/export/exported* /core/server/data/export/exported*
/docs /docs
/_site /_site
/content/data/*
/content/plugins/**/*
/content/themes/**/*
/content/images/**/* /content/images/**/*
!/content/themes/casper/**
!README.md
# Changelog, which is autogenerated, not committed # Changelog, which is autogenerated, not committed
CHANGELOG.md CHANGELOG.md

View file

@ -12,7 +12,16 @@ var path = require('path'),
buildGlob = [ buildGlob = [
'**', '**',
'!docs/**', '!docs/**',
'!_site/**',
'!content/images/**',
'content/images/README.md',
'!content/themes/**',
'content/themes/casper/**',
'!content/plugins/**',
'content/plugins/README.md',
'!node_modules/**', '!node_modules/**',
'!core/test/**',
'!core/client/assets/sass/**',
'!**/*.db*', '!**/*.db*',
'!*.db*', '!*.db*',
'!.sass*', '!.sass*',
@ -21,6 +30,8 @@ var path = require('path'),
'!.groc*', '!.groc*',
'!*.iml', '!*.iml',
'!config.js', '!config.js',
'!CONTRIBUTING.md',
'!SECURITY.md',
'!.travis.yml' '!.travis.yml'
], ],
@ -40,7 +51,8 @@ var path = require('path'),
dist: distDirectory, dist: distDirectory,
nightlyDist: path.join(distDirectory, 'nightly'), nightlyDist: path.join(distDirectory, 'nightly'),
weeklyDist: path.join(distDirectory, 'weekly'), weeklyDist: path.join(distDirectory, 'weekly'),
buildDist: path.join(distDirectory, 'build') buildDist: path.join(distDirectory, 'build'),
releaseDist: path.join(distDirectory, 'release')
}, },
buildType: 'Build', buildType: 'Build',
pkg: grunt.file.readJSON('package.json'), pkg: grunt.file.readJSON('package.json'),
@ -340,6 +352,14 @@ var path = require('path'),
expand: true, expand: true,
cwd: '<%= paths.buildBuild %>/', cwd: '<%= paths.buildBuild %>/',
src: ['**'] src: ['**']
},
release: {
options: {
archive: '<%= paths.releaseDist %>/Ghost-<%= pkg.version %>.zip'
},
expand: true,
cwd: '<%= paths.buildBuild %>/',
src: ['**']
} }
}, },
@ -813,6 +833,18 @@ var path = require('path'),
"compress:build" "compress:build"
]); ]);
grunt.registerTask('release', [
'shell:bourbon',
'sass:admin',
'handlebars',
'concat',
'uglify',
'changelog',
'clean:build',
'copy:build',
'compress:release'
]);
// Dev Mode; watch files and restart server on changes // Dev Mode; watch files and restart server on changes
grunt.registerTask("dev", [ grunt.registerTask("dev", [
"sass:admin", "sass:admin",

7
SECURITY.md Normal file
View file

@ -0,0 +1,7 @@
# Reporting Security Issues
If you discover a security issue in Ghost, please report it by sending an email to security[at]ghost[dot]org
This will allow us to assess the risk, and make a fix available before we add a bug report to the Github repo.
Thanks for helping make Ghost safe for everyone.

View file

@ -7,7 +7,7 @@
UploadUi = function ($dropzone, settings) { UploadUi = function ($dropzone, settings) {
var source, var source,
$url = '<div class="js-url"><input id="uploadurl" class="url" type="url" placeholder="http://"/></div>', $url = '<div class="js-url"><input class="url js-upload-url" type="url" placeholder="http://"/></div>',
$cancel = '<a class="image-cancel js-cancel"><span class="hidden">Delete</span></a>', $cancel = '<a class="image-cancel js-cancel"><span class="hidden">Delete</span></a>',
$progress = $('<div />', { $progress = $('<div />', {
"class" : "js-upload-progress progress progress-success active", "class" : "js-upload-progress progress progress-success active",
@ -57,7 +57,6 @@
}).attr('src', result); }).attr('src', result);
} }
preLoadImage(); preLoadImage();
}, },
bindFileUpload: function () { bindFileUpload: function () {
@ -168,17 +167,21 @@
$dropzone.find('div.description').before($url); $dropzone.find('div.description').before($url);
$dropzone.find('.js-button-accept').on('click', function () { $dropzone.find('.js-button-accept').on('click', function () {
val = $('#uploadurl').val(); val = $dropzone.find('.js-upload-url').val();
$dropzone.trigger('uploadstart', [$dropzone.attr('id')]);
$dropzone.find('div.description').hide(); $dropzone.find('div.description').hide();
$dropzone.find('.js-fileupload').removeClass('right'); $dropzone.find('.js-fileupload').removeClass('right');
$dropzone.find('.js-url').remove(); $dropzone.find('.js-url').remove();
$dropzone.find('button.centre').remove(); $dropzone.find('button.centre').remove();
if (val === "") {
$dropzone.trigger("uploadsuccess", 'http://');
self.initWithDropzone();
} else {
self.complete(val); self.complete(val);
}
}); });
}, },
initWithImage: function () { initWithImage: function () {
var self = this; var self = this, val;
// This is the start point if an image already exists // This is the start point if an image already exists
source = $dropzone.find('img.js-upload-target').attr('src'); source = $dropzone.find('img.js-upload-target').attr('src');
$dropzone.removeClass('image-uploader image-uploader-url').addClass('pre-image-uploader'); $dropzone.removeClass('image-uploader image-uploader-url').addClass('pre-image-uploader');
@ -187,6 +190,11 @@
$dropzone.find('.js-cancel').on('click', function () { $dropzone.find('.js-cancel').on('click', function () {
$dropzone.find('img.js-upload-target').attr({'src': ''}); $dropzone.find('img.js-upload-target').attr({'src': ''});
$dropzone.find('div.description').show(); $dropzone.find('div.description').show();
$dropzone.delay(2500).animate({opacity: 100}, 1000, function () {
self.init();
});
$dropzone.trigger("uploadsuccess", 'http://');
self.initWithDropzone(); self.initWithDropzone();
}); });
}, },

View file

@ -443,10 +443,9 @@
var filestorage = $('#entry-markdown-content').data('filestorage'); var filestorage = $('#entry-markdown-content').data('filestorage');
this.$('.js-drop-zone').upload({editor: true, fileStorage: filestorage}); this.$('.js-drop-zone').upload({editor: true, fileStorage: filestorage});
this.$('.js-drop-zone').on('uploadstart', $.proxy(this.disableEditor, this)); this.$('.js-drop-zone').on('uploadstart', $.proxy(this.disableEditor, this));
this.$('.js-drop-zone').on('uploadstart', this.uploadMgr.handleDownloadStart);
this.$('.js-drop-zone').on('uploadfailure', $.proxy(this.enableEditor, this)); this.$('.js-drop-zone').on('uploadfailure', $.proxy(this.enableEditor, this));
this.$('.js-drop-zone').on('uploadsuccess', $.proxy(this.enableEditor, this)); this.$('.js-drop-zone').on('uploadsuccess', $.proxy(this.enableEditor, this));
this.$('.js-drop-zone').on('uploadsuccess', this.uploadMgr.handleDownloadSuccess); this.$('.js-drop-zone').on('uploadsuccess', this.uploadMgr.handleUpload);
}, },
enableEditor: function () { enableEditor: function () {
@ -611,7 +610,7 @@
// TODO: hasMarker but no image? // TODO: hasMarker but no image?
} }
function handleDownloadStart(e) { function handleUpload(e, result_src) {
/*jslint regexp: true, bitwise: true */ /*jslint regexp: true, bitwise: true */
var line = findLine($(e.currentTarget).attr('id')), var line = findLine($(e.currentTarget).attr('id')),
lineNumber = editor.getLineNumber(line), lineNumber = editor.getLineNumber(line),
@ -636,9 +635,6 @@
); );
} }
} }
}
function handleDownloadSuccess(e, result_src) {
editor.replaceSelection(result_src); editor.replaceSelection(result_src);
} }
@ -655,8 +651,7 @@
// Public API // Public API
_.extend(this, { _.extend(this, {
getEditorValue: getEditorValue, getEditorValue: getEditorValue,
handleDownloadStart: handleDownloadStart, handleUpload: handleUpload
handleDownloadSuccess: handleDownloadSuccess
}); });
// initialise // initialise

View file

@ -14,6 +14,7 @@ var express = require('express'),
hbs = require('express-hbs'), hbs = require('express-hbs'),
Ghost = require('./ghost'), Ghost = require('./ghost'),
helpers = require('./server/helpers'), helpers = require('./server/helpers'),
middleware = require('./server/middleware'),
packageInfo = require('../package.json'), packageInfo = require('../package.json'),
// Variables // Variables
@ -193,7 +194,7 @@ function activateTheme() {
server.set('activeTheme', ghost.settings('activeTheme')); server.set('activeTheme', ghost.settings('activeTheme'));
server.enable(server.get('activeTheme')); server.enable(server.get('activeTheme'));
if (stackLocation) { if (stackLocation) {
server.stack[stackLocation].handle = whenEnabled(server.get('activeTheme'), express['static'](ghost.paths().activeTheme)); server.stack[stackLocation].handle = whenEnabled(server.get('activeTheme'), middleware.staticTheme(ghost));
} }
} }
@ -265,7 +266,7 @@ when(ghost.init()).then(function () {
server.use('/ghost', whenEnabled('admin', express['static'](path.join(__dirname, '/client/assets')))); server.use('/ghost', whenEnabled('admin', express['static'](path.join(__dirname, '/client/assets'))));
// Theme only config // Theme only config
server.use(whenEnabled(server.get('activeTheme'), express['static'](ghost.paths().activeTheme))); server.use(whenEnabled(server.get('activeTheme'), middleware.staticTheme(ghost)));
// Add in all trailing slashes // Add in all trailing slashes
server.use(slashes()); server.use(slashes());

View file

@ -95,7 +95,7 @@ GhostMailer.prototype.send = function (message) {
return when.reject(new Error('Email Error: Incomplete message data.')); return when.reject(new Error('Email Error: Incomplete message data.'));
} }
var from = 'ghost-mailer@' + url.parse(this.ghost.config().url).hostname, var from = this.ghost.config().mail.fromaddress || this.ghost.settings('email'),
to = message.to || this.ghost.settings('email'), to = message.to || this.ghost.settings('email'),
sendMail = nodefn.lift(this.transport.sendMail.bind(this.transport)); sendMail = nodefn.lift(this.transport.sendMail.bind(this.transport));

31
core/server/middleware.js Normal file
View file

@ -0,0 +1,31 @@
var _ = require('underscore'),
express = require('express'),
path = require('path');
function isBlackListedFileType(file) {
var blackListedFileTypes = ['.hbs', '.md', '.txt', '.json'],
ext = path.extname(file);
return _.contains(blackListedFileTypes, ext);
}
var middleware = {
staticTheme: function (g) {
var ghost = g;
return function blackListStatic(req, res, next) {
if (isBlackListedFileType(req.url)) {
return next();
}
return middleware.forwardToExpressStatic(ghost, req, res, next);
};
},
// to allow unit testing
forwardToExpressStatic: function (ghost, req, res, next) {
return express['static'](ghost.paths().activeTheme)(req, res, next);
}
};
module.exports = middleware;

View file

@ -0,0 +1,88 @@
/*globals describe, beforeEach, it*/
var assert = require('assert'),
should = require('should'),
sinon = require('sinon'),
when = require('when'),
express = require('express'),
middleware = require('../../server/middleware');
describe('Middleware', function () {
describe('staticTheme', function () {
var realExpressStatic = express.static;
beforeEach(function () {
sinon.stub(middleware, 'forwardToExpressStatic').yields();
});
afterEach(function () {
middleware.forwardToExpressStatic.restore();
});
it('should call next if hbs file type', function (done) {
var req = {
url: 'mytemplate.hbs'
};
middleware.staticTheme(null)(req, null, function (a) {
should.not.exist(a);
middleware.forwardToExpressStatic.calledOnce.should.be.false;
return done();
});
});
it('should call next if md file type', function (done) {
var req = {
url: 'README.md'
};
middleware.staticTheme(null)(req, null, function (a) {
should.not.exist(a);
middleware.forwardToExpressStatic.calledOnce.should.be.false;
return done();
});
});
it('should call next if txt file type', function (done) {
var req = {
url: 'LICENSE.txt'
};
middleware.staticTheme(null)(req, null, function (a) {
should.not.exist(a);
middleware.forwardToExpressStatic.calledOnce.should.be.false;
return done();
});
});
it('should call next if json file type', function (done) {
var req = {
url: 'sample.json'
}
middleware.staticTheme(null)(req, null, function (a) {
should.not.exist(a);
middleware.forwardToExpressStatic.calledOnce.should.be.false;
return done();
});
});
it('should call express.static if valid file type', function (done) {
var ghostStub = {
paths: function() {
return {activeTheme: 'ACTIVETHEME'};
}
};
var req = {
url: 'myvalidfile.css'
};
middleware.staticTheme(ghostStub)(req, null, function (req, res, next) {
middleware.forwardToExpressStatic.calledOnce.should.be.true;
assert.deepEqual(middleware.forwardToExpressStatic.args[0][0], ghostStub);
return done();
});
});
});
});

View file

@ -1,6 +1,6 @@
{ {
"name": "ghost", "name": "ghost",
"version": "0.3.1", "version": "0.3.2",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node index", "start": "node index",
@ -11,8 +11,8 @@
}, },
"engineStrict": true, "engineStrict": true,
"dependencies": { "dependencies": {
"express": "3.4.0", "express": "3.3.4",
"express-hbs": "0.3.0", "express-hbs": "0.2.2",
"connect-slashes": "0.0.9", "connect-slashes": "0.0.9",
"node-polyglot": "0.2.1", "node-polyglot": "0.2.1",
"moment": "2.1.0", "moment": "2.1.0",
@ -30,7 +30,10 @@
"downsize": "0.0.2", "downsize": "0.0.2",
"validator": "1.4.0", "validator": "1.4.0",
"rss": "0.2.0", "rss": "0.2.0",
"nodemailer": "~0.5.2" "nodemailer": "0.5.2"
},
"optionalDependencies": {
"mysql": "2.0.0-alpha9"
}, },
"devDependencies": { "devDependencies": {
"grunt": "~0.4.1", "grunt": "~0.4.1",