mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
parent
544289dc89
commit
310526b6c5
6 changed files with 210 additions and 3 deletions
|
@ -49,5 +49,9 @@ module.exports = {
|
|||
|
||||
get subscribers() {
|
||||
return shared.pipeline(require('./subscribers'), localUtils);
|
||||
},
|
||||
|
||||
get upload() {
|
||||
return shared.pipeline(require('./upload'), localUtils);
|
||||
}
|
||||
};
|
||||
|
|
31
core/server/api/v2/upload.js
Normal file
31
core/server/api/v2/upload.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const fs = require('fs-extra');
|
||||
const storage = require('../../adapters/storage');
|
||||
|
||||
module.exports = {
|
||||
docName: 'upload',
|
||||
image: {
|
||||
statusCode: 201,
|
||||
permissions: false,
|
||||
query(frame) {
|
||||
const store = storage.getStorage();
|
||||
|
||||
if (frame.files) {
|
||||
return Promise.map(frame.files, (file) => {
|
||||
return store
|
||||
.save(file)
|
||||
.finally(() => {
|
||||
// Remove uploaded file from tmp location
|
||||
return fs.unlink(file.path);
|
||||
});
|
||||
}).then((paths) => {
|
||||
return paths[0];
|
||||
});
|
||||
}
|
||||
|
||||
return store.save(frame.file).finally(() => {
|
||||
// Remove uploaded file from tmp location
|
||||
return fs.unlink(frame.file.path);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
|
@ -37,5 +37,9 @@ module.exports = {
|
|||
|
||||
get subscribers() {
|
||||
return require('./subscribers');
|
||||
},
|
||||
|
||||
get upload() {
|
||||
return require('./upload');
|
||||
}
|
||||
};
|
||||
|
|
9
core/server/api/v2/utils/serializers/output/upload.js
Normal file
9
core/server/api/v2/utils/serializers/output/upload.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
const debug = require('ghost-ignition').debug('api:v2:utils:serializers:output:upload');
|
||||
|
||||
module.exports = {
|
||||
image(models, apiConfig, frame) {
|
||||
debug('image');
|
||||
|
||||
return frame.response = models;
|
||||
}
|
||||
};
|
|
@ -171,7 +171,7 @@ module.exports = function apiRoutes() {
|
|||
upload.single('uploadimage'),
|
||||
shared.middlewares.validation.upload({type: 'images'}),
|
||||
shared.middlewares.image.normalize,
|
||||
api.http(api.uploads.add)
|
||||
apiv2.http(apiv2.upload.image)
|
||||
);
|
||||
|
||||
router.post('/uploads/profile-image',
|
||||
|
@ -180,7 +180,7 @@ module.exports = function apiRoutes() {
|
|||
shared.middlewares.validation.upload({type: 'images'}),
|
||||
shared.middlewares.validation.profileImage,
|
||||
shared.middlewares.image.normalize,
|
||||
api.http(api.uploads.add)
|
||||
apiv2.http(apiv2.upload.image)
|
||||
);
|
||||
|
||||
router.post('/db/backup', mw.authenticateClient('Ghost Backup'), api.http(api.db.backupContent));
|
||||
|
@ -190,7 +190,7 @@ module.exports = function apiRoutes() {
|
|||
upload.single('uploadimage'),
|
||||
shared.middlewares.validation.upload({type: 'icons'}),
|
||||
shared.middlewares.validation.blogIcon(),
|
||||
api.http(api.uploads.add)
|
||||
apiv2.http(apiv2.upload.image)
|
||||
);
|
||||
|
||||
// ## Invites
|
||||
|
|
159
core/test/functional/api/v2/admin/upload_spec.js
Normal file
159
core/test/functional/api/v2/admin/upload_spec.js
Normal file
|
@ -0,0 +1,159 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const should = require('should');
|
||||
const supertest = require('supertest');
|
||||
const localUtils = require('./utils');
|
||||
const testUtils = require('../../../../utils');
|
||||
const config = require('../../../../../../core/server/config');
|
||||
|
||||
const ghost = testUtils.startGhost;
|
||||
|
||||
describe('Upload API', function () {
|
||||
const images = [];
|
||||
let request;
|
||||
|
||||
before(function () {
|
||||
return ghost()
|
||||
.then(function () {
|
||||
request = supertest.agent(config.get('url'));
|
||||
})
|
||||
.then(function () {
|
||||
return localUtils.doAuth(request);
|
||||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
images.forEach(function (image) {
|
||||
fs.removeSync(config.get('paths').appRoot + image);
|
||||
});
|
||||
});
|
||||
|
||||
describe('success cases', function () {
|
||||
it('valid png', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/ghost-logo.png'))
|
||||
.expect(201)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
images.push(res.body);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('valid jpg', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/ghosticon.jpg'))
|
||||
.expect(201)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
images.push(res.body);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('valid gif', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/loadingcat.gif'))
|
||||
.expect(201)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
images.push(res.body);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('valid profile image', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads/profile-image'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/loadingcat_square.gif'))
|
||||
.expect(201)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
images.push(res.body);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('error cases', function () {
|
||||
it('import should fail without file', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.set('Accept', 'application/json')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(403)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('import should fail with unsupported file', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/csv/single-column-with-header.csv'))
|
||||
.expect(415)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('incorrect extension', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads'))
|
||||
.set('Origin', config.get('url'))
|
||||
.set('content-type', 'image/png')
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/ghost-logo.pngx'))
|
||||
.expect(415)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('import should fail if profile image is not square', function (done) {
|
||||
request.post(localUtils.API.getApiQuery('uploads/profile-image'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.attach('uploadimage', path.join(__dirname, '/../../../../utils/fixtures/images/favicon_not_square.png'))
|
||||
.expect(422)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue