1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-08-08 15:05:26 +02:00

Fix serving static files

This commit is contained in:
gohabereg 2019-02-25 18:38:23 +03:00 committed by georgyb
parent d54a5b740a
commit 4801b038cc
11 changed files with 57 additions and 29 deletions

1
.gitignore vendored
View file

@ -75,3 +75,4 @@ typings/
# Uploads # Uploads
/public/uploads /public/uploads
/public/uploads_test

View file

@ -1,4 +1,5 @@
{ {
"port": 3000, "port": 3000,
"database": ".db" "database": ".db",
"uploads": "public/uploads"
} }

View file

@ -15,7 +15,8 @@ if (fs.existsSync(path.resolve(__dirname, configPath))) {
} else { } else {
config = { config = {
database: '.db', database: '.db',
port: 3000 port: 3000,
uploads: 'public/uploads'
}; };
} }

View file

@ -1,4 +1,5 @@
{ {
"port": 3000, "port": 3000,
"database": ".db" "database": ".db",
"uploads": "public/uploads"
} }

View file

@ -1,5 +1,6 @@
{ {
"port": 3001, "port": 3001,
"database": ".testdb", "database": ".testdb",
"rcFile": "./test/.codexdocsrc" "rcFile": "./test/.codexdocsrc",
"uploads": "public/uploads_test"
} }

View file

@ -26,6 +26,7 @@
"express": "~4.16.0", "express": "~4.16.0",
"file-type": "^10.7.1", "file-type": "^10.7.1",
"http-errors": "~1.7.1", "http-errors": "~1.7.1",
"mime": "^2.4.0",
"module-dispatcher": "^2.0.0", "module-dispatcher": "^2.0.0",
"morgan": "~1.9.0", "morgan": "~1.9.0",
"multer": "^1.3.1", "multer": "^1.3.1",
@ -46,8 +47,8 @@
"babel-loader": "^8.0.2", "babel-loader": "^8.0.2",
"chai": "^4.1.2", "chai": "^4.1.2",
"chai-http": "^4.0.0", "chai-http": "^4.0.0",
"codex.editor.image": "^2.0.3",
"codex.editor.code": "^2.3.1", "codex.editor.code": "^2.3.1",
"codex.editor.image": "^2.0.3",
"codex.editor.inline-code": "^1.2.0", "codex.editor.inline-code": "^1.2.0",
"codex.editor.list": "^1.2.3", "codex.editor.list": "^1.2.3",
"codex.editor.marker": "^1.0.1", "codex.editor.marker": "^1.0.1",
@ -79,6 +80,7 @@
"postcss-nested-ancestors": "^2.0.0", "postcss-nested-ancestors": "^2.0.0",
"postcss-nesting": "^7.0.0", "postcss-nesting": "^7.0.0",
"postcss-smart-import": "^0.7.6", "postcss-smart-import": "^0.7.6",
"rimraf": "^2.6.3",
"sinon": "^7.0.0", "sinon": "^7.0.0",
"webpack": "^4.17.1", "webpack": "^4.17.1",
"webpack-cli": "^3.1.0" "webpack-cli": "^3.1.0"

View file

@ -4,8 +4,6 @@ const path = require('path');
const cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
const logger = require('morgan'); const logger = require('morgan');
const rcParser = require('./utils/rcparser'); const rcParser = require('./utils/rcparser');
const FileModel = require('./models/file');
const routes = require('./routes'); const routes = require('./routes');
const app = express(); const app = express();
@ -22,19 +20,7 @@ app.use(logger('dev'));
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use(cookieParser()); app.use(cookieParser());
app.use(express.static( app.use(express.static(path.join(__dirname, '../public')));
path.join(__dirname, '../public'),
{
setHeaders: async (res, pathToFile) => {
const filename = path.basename(pathToFile);
const file = await FileModel.getByFilename(filename);
if (file._id && file.mimetype) {
res.setHeader('content-type', file.mimetype);
}
}
}
));
app.use('/', routes); app.use('/', routes);
// catch 404 and forward to error handler // catch 404 and forward to error handler

View file

@ -1,10 +1,12 @@
const fileType = require('file-type'); const fileType = require('file-type');
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const fs = require('fs'); const fs = require('fs');
const nodePath = require('path');
const Model = require('../models/file'); const Model = require('../models/file');
const { random16 } = require('../utils/crypto'); const { random16 } = require('../utils/crypto');
const { deepMerge } = require('../utils/objects'); const { deepMerge } = require('../utils/objects');
const config = require('../../config');
/** /**
* @class Transport * @class Transport
@ -26,7 +28,7 @@ class Transport {
* @return {Promise<FileData>} * @return {Promise<FileData>}
*/ */
static async save(multerData, map) { static async save(multerData, map) {
const { originalname: name, filename, path, size, mimetype } = multerData; const { originalname: name, path, filename, size, mimetype } = multerData;
const file = new Model({ name, filename, path, size, mimetype }); const file = new Model({ name, filename, path, size, mimetype });
@ -52,14 +54,15 @@ class Transport {
const buffer = await fetchedFile.buffer(); const buffer = await fetchedFile.buffer();
const filename = await random16(); const filename = await random16();
fs.writeFileSync(`public/uploads/${filename}`, buffer);
const type = fileType(buffer); const type = fileType(buffer);
const ext = type ? type.ext : nodePath.extname(url).slice(1);
fs.writeFileSync(`${config.uploads}/${filename}.${ext}`, buffer);
const file = new Model({ const file = new Model({
name: url, name: url,
filename, filename: `${filename}.${ext}`,
path: `/uploads/${filename}`, path: `${config.uploads}/${filename}.${ext}`,
size: buffer.length, size: buffer.length,
mimetype: type ? type.mime : fetchedFile.headers.get('content-type') mimetype: type ? type.mime : fetchedFile.headers.get('content-type')
}); });

View file

@ -1,13 +1,31 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const multer = require('multer'); const multer = require('multer');
const mime = require('mime')
const Transport = require('../../controllers/transport'); const Transport = require('../../controllers/transport');
const { random16 } = require('../../utils/crypto');
const config = require('../../../config');
/**
* Multer storage for uploaded files and images
* @type {DiskStorage|DiskStorage}
*/
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, config.uploads || 'public/uploads');
},
filename: async (req, file, cb) => {
const filename = await random16();
cb(null, `${filename}.${mime.getExtension(file.mimetype)}`);
}
})
/** /**
* Multer middleware for image uploading * Multer middleware for image uploading
*/ */
const imageUploader = multer({ const imageUploader = multer({
dest: 'public/uploads/', storage,
fileFilter: (req, file, cb) => { fileFilter: (req, file, cb) => {
if (!/image/.test(file.mimetype)) { if (!/image/.test(file.mimetype)) {
cb(null, false); cb(null, false);
@ -22,7 +40,7 @@ const imageUploader = multer({
* Multer middleware for file uploading * Multer middleware for file uploading
*/ */
const fileUploader = multer({ const fileUploader = multer({
dest: 'public/uploads/' storage
}).fields([ { name: 'file', maxCount: 1 } ]); }).fields([ { name: 'file', maxCount: 1 } ]);
/** /**

View file

@ -3,6 +3,7 @@ const path = require('path');
const fileType = require('file-type'); const fileType = require('file-type');
const chai = require('chai'); const chai = require('chai');
const chaiHTTP = require('chai-http'); const chaiHTTP = require('chai-http');
const rimraf = require('rimraf');
const {expect} = chai; const {expect} = chai;
const {app} = require('../../bin/www'); const {app} = require('../../bin/www');
@ -17,6 +18,10 @@ describe('Transport routes: ', () => {
before(async () => { before(async () => {
agent = chai.request.agent(app); agent = chai.request.agent(app);
if (!fs.existsSync('./' + config.uploads)) {
fs.mkdirSync('./' + config.uploads);
}
}); });
after(async () => { after(async () => {
@ -25,6 +30,10 @@ describe('Transport routes: ', () => {
if (fs.existsSync(pathToDB)) { if (fs.existsSync(pathToDB)) {
fs.unlinkSync(pathToDB); fs.unlinkSync(pathToDB);
} }
if (fs.existsSync('./' + config.uploads)) {
rimraf.sync('./' + config.uploads);
}
}); });
it('Uploading an image', async () => { it('Uploading an image', async () => {
@ -102,7 +111,7 @@ describe('Transport routes: ', () => {
.get(file.path); .get(file.path);
expect(getRes).to.have.status(200); expect(getRes).to.have.status(200);
expect(getRes).to.have.header('content-type', file.mimetype); expect(getRes).to.have.header('content-type', new RegExp(`^${file.mimetype}`));
}); });
it('Uploading a file with map option', async () => { it('Uploading a file with map option', async () => {

View file

@ -3730,6 +3730,11 @@ mime@^1.4.1:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
mime@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6"
integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==
mimic-fn@^1.0.0: mimic-fn@^1.0.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@ -5293,7 +5298,7 @@ rgba-regex@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2:
version "2.6.3" version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
dependencies: dependencies: