feat: access cached upload file + ignore common page extensions
This commit is contained in:
		| @@ -213,7 +213,7 @@ export default { | |||||||
|       } |       } | ||||||
|       for (let file of files) { |       for (let file of files) { | ||||||
|         file.setMetadata({ |         file.setMetadata({ | ||||||
|           path: '/universe' |           path: 'test' | ||||||
|         }) |         }) | ||||||
|       } |       } | ||||||
|       await this.$refs.pond.processFiles() |       await this.$refs.pond.processFiles() | ||||||
|   | |||||||
| @@ -97,4 +97,8 @@ reservedPaths: | |||||||
|   - img |   - img | ||||||
|   - js |   - js | ||||||
|   - svg |   - svg | ||||||
|  | pageExtensions: | ||||||
|  |   - md | ||||||
|  |   - html | ||||||
|  |   - txt | ||||||
| # --------------------------------- | # --------------------------------- | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ router.get('/healthz', (req, res, next) => { | |||||||
|  * Create/Edit document |  * Create/Edit document | ||||||
|  */ |  */ | ||||||
| router.get(['/e', '/e/*'], async (req, res, next) => { | router.get(['/e', '/e/*'], async (req, res, next) => { | ||||||
|   const pageArgs = pageHelper.parsePath(req.path) |   const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) | ||||||
|  |  | ||||||
|   if (pageHelper.isReservedPath(pageArgs.path)) { |   if (pageHelper.isReservedPath(pageArgs.path)) { | ||||||
|     return next(new Error('Cannot create this page because it starts with a system reserved path.')) |     return next(new Error('Cannot create this page because it starts with a system reserved path.')) | ||||||
| @@ -93,7 +93,7 @@ router.get(['/p', '/p/*'], (req, res, next) => { | |||||||
|  * History |  * History | ||||||
|  */ |  */ | ||||||
| router.get(['/h', '/h/*'], async (req, res, next) => { | router.get(['/h', '/h/*'], async (req, res, next) => { | ||||||
|   const pageArgs = pageHelper.parsePath(req.path) |   const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) | ||||||
|  |  | ||||||
|   if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { |   if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { | ||||||
|     _.set(res.locals, 'pageMeta.title', 'Unauthorized') |     _.set(res.locals, 'pageMeta.title', 'Unauthorized') | ||||||
| @@ -119,7 +119,7 @@ router.get(['/h', '/h/*'], async (req, res, next) => { | |||||||
|  * Source |  * Source | ||||||
|  */ |  */ | ||||||
| router.get(['/s', '/s/*'], async (req, res, next) => { | router.get(['/s', '/s/*'], async (req, res, next) => { | ||||||
|   const pageArgs = pageHelper.parsePath(req.path) |   const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) | ||||||
|  |  | ||||||
|   if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { |   if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { | ||||||
|     return res.render('unauthorized', { action: 'source' }) |     return res.render('unauthorized', { action: 'source' }) | ||||||
| @@ -141,14 +141,17 @@ router.get(['/s', '/s/*'], async (req, res, next) => { | |||||||
| }) | }) | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * View document |  * View document / asset | ||||||
|  */ |  */ | ||||||
| router.get('/*', async (req, res, next) => { | router.get('/*', async (req, res, next) => { | ||||||
|   const pageArgs = pageHelper.parsePath(req.path) |   const stripExt = _.some(WIKI.data.pageExtensions, ext => _.endsWith(req.path, `.${ext}`)) | ||||||
|  |   const pageArgs = pageHelper.parsePath(req.path, { stripExt }) | ||||||
|  |   const isPage = (stripExt || pageArgs.path.indexOf('.') === -1) | ||||||
|  |  | ||||||
|  |   if (isPage) { | ||||||
|     if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { |     if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) { | ||||||
|       _.set(res.locals, 'pageMeta.title', 'Unauthorized') |       _.set(res.locals, 'pageMeta.title', 'Unauthorized') | ||||||
|     return res.render('unauthorized', { action: 'view' }) |       return res.status(403).render('unauthorized', { action: 'view' }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const page = await WIKI.models.pages.getPage({ |     const page = await WIKI.models.pages.getPage({ | ||||||
| @@ -175,9 +178,16 @@ router.get('/*', async (req, res, next) => { | |||||||
|       if (WIKI.auth.checkAccess(req.user, ['write:pages'], pageArgs)) { |       if (WIKI.auth.checkAccess(req.user, ['write:pages'], pageArgs)) { | ||||||
|         res.status(404).render('new', { pagePath: req.path }) |         res.status(404).render('new', { pagePath: req.path }) | ||||||
|       } else { |       } else { | ||||||
|       res.render('notfound', { action: 'view' }) |         res.status(404).render('notfound', { action: 'view' }) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } else { | ||||||
|  |     if (!WIKI.auth.checkAccess(req.user, ['read:assets'], pageArgs)) { | ||||||
|  |       return res.sendStatus(403) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     await WIKI.models.assets.getAsset(pageArgs.path, res) | ||||||
|  |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
| module.exports = router | module.exports = router | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| const qs = require('querystring') | const qs = require('querystring') | ||||||
| const _ = require('lodash') | const _ = require('lodash') | ||||||
| const crypto = require('crypto') | const crypto = require('crypto') | ||||||
|  | const path = require('path') | ||||||
|  |  | ||||||
| const localeSegmentRegex = /^[A-Z]{2}(-[A-Z]{2})?$/i | const localeSegmentRegex = /^[A-Z]{2}(-[A-Z]{2})?$/i | ||||||
|  |  | ||||||
| @@ -10,7 +11,7 @@ module.exports = { | |||||||
|   /** |   /** | ||||||
|    * Parse raw url path and make it safe |    * Parse raw url path and make it safe | ||||||
|    */ |    */ | ||||||
|   parsePath (rawPath) { |   parsePath (rawPath, opts = {}) { | ||||||
|     let pathObj = { |     let pathObj = { | ||||||
|       locale: 'en', |       locale: 'en', | ||||||
|       path: 'home', |       path: 'home', | ||||||
| @@ -32,6 +33,17 @@ module.exports = { | |||||||
|       pathObj.locale = pathParts[0] |       pathObj.locale = pathParts[0] | ||||||
|       pathParts.shift() |       pathParts.shift() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Strip extension | ||||||
|  |     if (opts.stripExt) { | ||||||
|  |       const lastPart = _.last(pathParts) | ||||||
|  |       if (lastPart.indexOf('.') > 0) { | ||||||
|  |         pathParts.pop() | ||||||
|  |         const lastPartMeta = path.parse(lastPart) | ||||||
|  |         pathParts.push(lastPartMeta.name) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pathObj.path = _.join(pathParts, '/') |     pathObj.path = _.join(pathParts, '/') | ||||||
|     return pathObj |     return pathObj | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -94,4 +94,30 @@ module.exports = class Asset extends Model { | |||||||
|     // Move temp upload to cache |     // Move temp upload to cache | ||||||
|     await fs.move(opts.path, path.join(process.cwd(), `data/cache/${fileHash}.dat`)) |     await fs.move(opts.path, path.join(process.cwd(), `data/cache/${fileHash}.dat`)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static async getAsset(assetPath, res) { | ||||||
|  |     let asset = await WIKI.models.assets.getAssetFromCache(assetPath, res) | ||||||
|  |     if (!asset) { | ||||||
|  |       // asset = await WIKI.models.assets.getAssetFromDb(assetPath, res) | ||||||
|  |       // if (asset) { | ||||||
|  |       //   await WIKI.models.assets.saveAssetToCache(asset) | ||||||
|  |       // } | ||||||
|  |       res.sendStatus(404) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async getAssetFromCache(assetPath, res) { | ||||||
|  |     const fileHash = assetHelper.generateHash(assetPath) | ||||||
|  |     const cachePath = path.join(process.cwd(), `data/cache/${fileHash}.dat`) | ||||||
|  |  | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |       res.sendFile(cachePath, { dotfiles: 'deny' }, err => { | ||||||
|  |         if (err) { | ||||||
|  |           resolve(false) | ||||||
|  |         } else { | ||||||
|  |           resolve(true) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }) | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user