fix: entries helper paths
This commit is contained in:
parent
d4b73be1e7
commit
4ba4f29028
@ -45,6 +45,8 @@ const fs = Promise.promisifyAll(require('fs-extra'))
|
|||||||
const klaw = require('klaw')
|
const klaw = require('klaw')
|
||||||
const Cron = require('cron').CronJob
|
const Cron = require('cron').CronJob
|
||||||
|
|
||||||
|
const entryHelper = require('./helpers/entry')
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Start Cron
|
// Start Cron
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
@ -94,8 +96,8 @@ db.onReady.then(() => {
|
|||||||
|
|
||||||
klaw(repoPath).on('data', function (item) {
|
klaw(repoPath).on('data', function (item) {
|
||||||
if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') {
|
if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') {
|
||||||
let entryPath = entries.parsePath(entries.getEntryPathFromFullPath(item.path))
|
let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path))
|
||||||
let cachePath = entries.getCachePath(entryPath)
|
let cachePath = entryHelper.getCachePath(entryPath)
|
||||||
|
|
||||||
// -> Purge outdated cache
|
// -> Purge outdated cache
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ const express = require('express')
|
|||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
const entryHelper = require('../helpers/entry')
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// EDIT MODE
|
// EDIT MODE
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@ -16,7 +18,7 @@ router.get('/edit/*', (req, res, next) => {
|
|||||||
return res.render('error-forbidden')
|
return res.render('error-forbidden')
|
||||||
}
|
}
|
||||||
|
|
||||||
let safePath = entries.parsePath(_.replace(req.path, '/edit', ''))
|
let safePath = entryHelper.parsePath(_.replace(req.path, '/edit', ''))
|
||||||
|
|
||||||
entries.fetchOriginal(safePath, {
|
entries.fetchOriginal(safePath, {
|
||||||
parseMarkdown: false,
|
parseMarkdown: false,
|
||||||
@ -48,7 +50,7 @@ router.put('/edit/*', (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let safePath = entries.parsePath(_.replace(req.path, '/edit', ''))
|
let safePath = entryHelper.parsePath(_.replace(req.path, '/edit', ''))
|
||||||
|
|
||||||
entries.update(safePath, req.body.markdown, req.user).then(() => {
|
entries.update(safePath, req.body.markdown, req.user).then(() => {
|
||||||
return res.json({
|
return res.json({
|
||||||
@ -78,7 +80,7 @@ router.get('/create/*', (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let safePath = entries.parsePath(_.replace(req.path, '/create', ''))
|
let safePath = entryHelper.parsePath(_.replace(req.path, '/create', ''))
|
||||||
|
|
||||||
entries.exists(safePath).then((docExists) => {
|
entries.exists(safePath).then((docExists) => {
|
||||||
if (!docExists) {
|
if (!docExists) {
|
||||||
@ -116,7 +118,7 @@ router.put('/create/*', (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let safePath = entries.parsePath(_.replace(req.path, '/create', ''))
|
let safePath = entryHelper.parsePath(_.replace(req.path, '/create', ''))
|
||||||
|
|
||||||
entries.create(safePath, req.body.markdown, req.user).then(() => {
|
entries.create(safePath, req.body.markdown, req.user).then(() => {
|
||||||
return res.json({
|
return res.json({
|
||||||
@ -153,7 +155,7 @@ router.use((req, res, next) => {
|
|||||||
* View source of a document
|
* View source of a document
|
||||||
*/
|
*/
|
||||||
router.get('/source/*', (req, res, next) => {
|
router.get('/source/*', (req, res, next) => {
|
||||||
let safePath = entries.parsePath(_.replace(req.path, '/source', ''))
|
let safePath = entryHelper.parsePath(_.replace(req.path, '/source', ''))
|
||||||
|
|
||||||
entries.fetchOriginal(safePath, {
|
entries.fetchOriginal(safePath, {
|
||||||
parseMarkdown: false,
|
parseMarkdown: false,
|
||||||
@ -181,7 +183,7 @@ router.get('/source/*', (req, res, next) => {
|
|||||||
* View document
|
* View document
|
||||||
*/
|
*/
|
||||||
router.get('/*', (req, res, next) => {
|
router.get('/*', (req, res, next) => {
|
||||||
let safePath = entries.parsePath(req.path)
|
let safePath = entryHelper.parsePath(req.path)
|
||||||
|
|
||||||
entries.fetch(safePath).then((pageData) => {
|
entries.fetch(safePath).then((pageData) => {
|
||||||
if (pageData) {
|
if (pageData) {
|
||||||
@ -221,7 +223,7 @@ router.put('/*', (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let safePath = entries.parsePath(req.path)
|
let safePath = entryHelper.parsePath(req.path)
|
||||||
|
|
||||||
if (_.isEmpty(req.body.move)) {
|
if (_.isEmpty(req.body.move)) {
|
||||||
return res.json({
|
return res.json({
|
||||||
@ -230,7 +232,7 @@ router.put('/*', (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let safeNewPath = entries.parsePath(req.body.move)
|
let safeNewPath = entryHelper.parsePath(req.body.move)
|
||||||
|
|
||||||
entries.move(safePath, safeNewPath, req.user).then(() => {
|
entries.move(safePath, safeNewPath, req.user).then(() => {
|
||||||
res.json({
|
res.json({
|
||||||
|
60
server/helpers/entry.js
Normal file
60
server/helpers/entry.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const crypto = require('crypto')
|
||||||
|
const path = require('path')
|
||||||
|
const qs = require('querystring')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Parse raw url path and make it safe
|
||||||
|
*
|
||||||
|
* @param {String} urlPath The url path
|
||||||
|
* @return {String} Safe entry path
|
||||||
|
*/
|
||||||
|
parsePath (urlPath) {
|
||||||
|
urlPath = qs.unescape(urlPath)
|
||||||
|
let wlist = new RegExp('(?!([^a-z0-9]|' + appdata.regex.cjk.source + '|[/-]))', 'g')
|
||||||
|
|
||||||
|
urlPath = _.toLower(urlPath).replace(wlist, '')
|
||||||
|
|
||||||
|
if (urlPath === '/') {
|
||||||
|
urlPath = 'home'
|
||||||
|
}
|
||||||
|
|
||||||
|
let urlParts = _.filter(_.split(urlPath, '/'), (p) => { return !_.isEmpty(p) })
|
||||||
|
|
||||||
|
return _.join(urlParts, '/')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the full original path of a document.
|
||||||
|
*
|
||||||
|
* @param {String} entryPath The entry path
|
||||||
|
* @return {String} The full path.
|
||||||
|
*/
|
||||||
|
getFullPath (entryPath) {
|
||||||
|
return path.join(appdata.repoPath, entryPath + '.md')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the full cache path of a document.
|
||||||
|
*
|
||||||
|
* @param {String} entryPath The entry path
|
||||||
|
* @return {String} The full cache path.
|
||||||
|
*/
|
||||||
|
getCachePath (entryPath) {
|
||||||
|
return path.join(appdata.cachePath, crypto.createHash('md5').update(entryPath).digest('hex') + '.json')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entry path from full path.
|
||||||
|
*
|
||||||
|
* @param {String} fullPath The full path
|
||||||
|
* @return {String} The entry path
|
||||||
|
*/
|
||||||
|
getEntryPathFromFullPath (fullPath) {
|
||||||
|
let absRepoPath = path.resolve(ROOTPATH, appdata.repoPath)
|
||||||
|
return _.chain(fullPath).replace(absRepoPath, '').replace('.md', '').replace(new RegExp('\\\\', 'g'), '/').value()
|
||||||
|
}
|
||||||
|
}
|
7
server/helpers/security.js
Normal file
7
server/helpers/security.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
sanitizeCommitUser (user) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@ const Promise = require('bluebird')
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const fs = Promise.promisifyAll(require('fs-extra'))
|
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const crypto = require('crypto')
|
|
||||||
const qs = require('querystring')
|
const entryHelper = require('../helpers/entry')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entries Model
|
* Entries Model
|
||||||
@ -25,6 +25,8 @@ module.exports = {
|
|||||||
|
|
||||||
self._repoPath = path.resolve(ROOTPATH, appconfig.paths.repo)
|
self._repoPath = path.resolve(ROOTPATH, appconfig.paths.repo)
|
||||||
self._cachePath = path.resolve(ROOTPATH, appconfig.paths.data, 'cache')
|
self._cachePath = path.resolve(ROOTPATH, appconfig.paths.data, 'cache')
|
||||||
|
appdata.repoPath = self._repoPath
|
||||||
|
appdata.cachePath = self._cachePath
|
||||||
|
|
||||||
return self
|
return self
|
||||||
},
|
},
|
||||||
@ -61,7 +63,7 @@ module.exports = {
|
|||||||
fetch (entryPath) {
|
fetch (entryPath) {
|
||||||
let self = this
|
let self = this
|
||||||
|
|
||||||
let cpath = self.getCachePath(entryPath)
|
let cpath = entryHelper.getCachePath(entryPath)
|
||||||
|
|
||||||
return fs.statAsync(cpath).then((st) => {
|
return fs.statAsync(cpath).then((st) => {
|
||||||
return st.isFile()
|
return st.isFile()
|
||||||
@ -96,8 +98,8 @@ module.exports = {
|
|||||||
fetchOriginal (entryPath, options) {
|
fetchOriginal (entryPath, options) {
|
||||||
let self = this
|
let self = this
|
||||||
|
|
||||||
let fpath = self.getFullPath(entryPath)
|
let fpath = entryHelper.getFullPath(entryPath)
|
||||||
let cpath = self.getCachePath(entryPath)
|
let cpath = entryHelper.getCachePath(entryPath)
|
||||||
|
|
||||||
options = _.defaults(options, {
|
options = _.defaults(options, {
|
||||||
parseMarkdown: true,
|
parseMarkdown: true,
|
||||||
@ -157,27 +159,6 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse raw url path and make it safe
|
|
||||||
*
|
|
||||||
* @param {String} urlPath The url path
|
|
||||||
* @return {String} Safe entry path
|
|
||||||
*/
|
|
||||||
parsePath (urlPath) {
|
|
||||||
urlPath = qs.unescape(urlPath)
|
|
||||||
let wlist = new RegExp('(?!([^a-z0-9]|' + appdata.regex.cjk.source + '|[/-]))', 'g')
|
|
||||||
|
|
||||||
urlPath = _.toLower(urlPath).replace(wlist, '')
|
|
||||||
|
|
||||||
if (urlPath === '/') {
|
|
||||||
urlPath = 'home'
|
|
||||||
}
|
|
||||||
|
|
||||||
let urlParts = _.filter(_.split(urlPath, '/'), (p) => { return !_.isEmpty(p) })
|
|
||||||
|
|
||||||
return _.join(urlParts, '/')
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the parent information.
|
* Gets the parent information.
|
||||||
*
|
*
|
||||||
@ -185,13 +166,11 @@ module.exports = {
|
|||||||
* @return {Promise<Object|False>} The parent information.
|
* @return {Promise<Object|False>} The parent information.
|
||||||
*/
|
*/
|
||||||
getParentInfo (entryPath) {
|
getParentInfo (entryPath) {
|
||||||
let self = this
|
|
||||||
|
|
||||||
if (_.includes(entryPath, '/')) {
|
if (_.includes(entryPath, '/')) {
|
||||||
let parentParts = _.initial(_.split(entryPath, '/'))
|
let parentParts = _.initial(_.split(entryPath, '/'))
|
||||||
let parentPath = _.join(parentParts, '/')
|
let parentPath = _.join(parentParts, '/')
|
||||||
let parentFile = _.last(parentParts)
|
let parentFile = _.last(parentParts)
|
||||||
let fpath = self.getFullPath(parentPath)
|
let fpath = entryHelper.getFullPath(parentPath)
|
||||||
|
|
||||||
return fs.statAsync(fpath).then((st) => {
|
return fs.statAsync(fpath).then((st) => {
|
||||||
if (st.isFile()) {
|
if (st.isFile()) {
|
||||||
@ -213,37 +192,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the full original path of a document.
|
|
||||||
*
|
|
||||||
* @param {String} entryPath The entry path
|
|
||||||
* @return {String} The full path.
|
|
||||||
*/
|
|
||||||
getFullPath (entryPath) {
|
|
||||||
return path.join(this._repoPath, entryPath + '.md')
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the full cache path of a document.
|
|
||||||
*
|
|
||||||
* @param {String} entryPath The entry path
|
|
||||||
* @return {String} The full cache path.
|
|
||||||
*/
|
|
||||||
getCachePath (entryPath) {
|
|
||||||
return path.join(this._cachePath, crypto.createHash('md5').update(entryPath).digest('hex') + '.json')
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the entry path from full path.
|
|
||||||
*
|
|
||||||
* @param {String} fullPath The full path
|
|
||||||
* @return {String} The entry path
|
|
||||||
*/
|
|
||||||
getEntryPathFromFullPath (fullPath) {
|
|
||||||
let absRepoPath = path.resolve(ROOTPATH, this._repoPath)
|
|
||||||
return _.chain(fullPath).replace(absRepoPath, '').replace('.md', '').replace(new RegExp('\\\\', 'g'), '/').value()
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an existing document
|
* Update an existing document
|
||||||
*
|
*
|
||||||
@ -254,7 +202,7 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
update (entryPath, contents, author) {
|
update (entryPath, contents, author) {
|
||||||
let self = this
|
let self = this
|
||||||
let fpath = self.getFullPath(entryPath)
|
let fpath = entryHelper.getFullPath(entryPath)
|
||||||
|
|
||||||
return fs.statAsync(fpath).then((st) => {
|
return fs.statAsync(fpath).then((st) => {
|
||||||
if (st.isFile()) {
|
if (st.isFile()) {
|
||||||
@ -385,8 +333,7 @@ module.exports = {
|
|||||||
* @return {Promise<Boolean>} True on success, false on failure
|
* @return {Promise<Boolean>} True on success, false on failure
|
||||||
*/
|
*/
|
||||||
makePersistent (entryPath, contents, author) {
|
makePersistent (entryPath, contents, author) {
|
||||||
let self = this
|
let fpath = entryHelper.getFullPath(entryPath)
|
||||||
let fpath = self.getFullPath(entryPath)
|
|
||||||
|
|
||||||
return fs.outputFileAsync(fpath, contents).then(() => {
|
return fs.outputFileAsync(fpath, contents).then(() => {
|
||||||
return git.commitDocument(entryPath, author)
|
return git.commitDocument(entryPath, author)
|
||||||
@ -412,7 +359,7 @@ module.exports = {
|
|||||||
return git.commitDocument(newEntryPath, author).then(() => {
|
return git.commitDocument(newEntryPath, author).then(() => {
|
||||||
// Delete old cache version
|
// Delete old cache version
|
||||||
|
|
||||||
let oldEntryCachePath = self.getCachePath(entryPath)
|
let oldEntryCachePath = entryHelper.getCachePath(entryPath)
|
||||||
fs.unlinkAsync(oldEntryCachePath).catch((err) => { return true }) // eslint-disable-line handle-callback-err
|
fs.unlinkAsync(oldEntryCachePath).catch((err) => { return true }) // eslint-disable-line handle-callback-err
|
||||||
|
|
||||||
// Delete old index entry
|
// Delete old index entry
|
||||||
@ -437,7 +384,7 @@ module.exports = {
|
|||||||
getStarter (entryPath) {
|
getStarter (entryPath) {
|
||||||
let formattedTitle = _.startCase(_.last(_.split(entryPath, '/')))
|
let formattedTitle = _.startCase(_.last(_.split(entryPath, '/')))
|
||||||
|
|
||||||
return fs.readFileAsync(path.join(ROOTPATH, 'client/content/create.md'), 'utf8').then((contents) => {
|
return fs.readFileAsync(path.join(SERVERPATH, 'app/content/create.md'), 'utf8').then((contents) => {
|
||||||
return _.replace(contents, new RegExp('{TITLE}', 'g'), formattedTitle)
|
return _.replace(contents, new RegExp('{TITLE}', 'g'), formattedTitle)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user