feat: add Page Rules For Matching Tags (#1418)
* Added Page Rules For Matching Tags * fix: use T as Tag Match icon * fix: reorder page rules in checkAccess * fix: common controller tags code refactor Co-authored-by: Nicolas Giard <github@ngpixel.com>
This commit is contained in:
parent
4e9d4071fd
commit
b82c788e5c
@ -157,8 +157,8 @@
|
|||||||
solo
|
solo
|
||||||
v-model='rule.path'
|
v-model='rule.path'
|
||||||
label='Path'
|
label='Path'
|
||||||
:prefix='rule.match !== `END` ? `/` : null'
|
:prefix='(rule.match !== `END` && rule.match !== `TAG`) ? `/` : null'
|
||||||
:placeholder='rule.match === `REGEX` ? `Regular Expression` : `Path`'
|
:placeholder='rule.match === `REGEX` ? `Regular Expression` : rule.match === `TAG` ? `Tag` : `Path`'
|
||||||
:suffix='rule.match === `REGEX` ? `/` : null'
|
:suffix='rule.match === `REGEX` ? `/` : null'
|
||||||
hide-details
|
hide-details
|
||||||
:color='$vuetify.theme.dark ? `grey` : `blue-grey`'
|
:color='$vuetify.theme.dark ? `grey` : `blue-grey`'
|
||||||
@ -181,6 +181,8 @@
|
|||||||
strong Path Ends With...
|
strong Path Ends With...
|
||||||
li
|
li
|
||||||
strong Path Matches Regex...
|
strong Path Matches Regex...
|
||||||
|
li
|
||||||
|
strong Tag Matches...
|
||||||
li
|
li
|
||||||
strong Path Is Exactly...
|
strong Path Is Exactly...
|
||||||
em.caption.pl-1 (highest)
|
em.caption.pl-1 (highest)
|
||||||
@ -222,7 +224,8 @@ export default {
|
|||||||
{ text: 'Path Starts With...', value: 'START', icon: '/...' },
|
{ text: 'Path Starts With...', value: 'START', icon: '/...' },
|
||||||
{ text: 'Path is Exactly...', value: 'EXACT', icon: '=' },
|
{ text: 'Path is Exactly...', value: 'EXACT', icon: '=' },
|
||||||
{ text: 'Path Ends With...', value: 'END', icon: '.../' },
|
{ text: 'Path Ends With...', value: 'END', icon: '.../' },
|
||||||
{ text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' }
|
{ text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' },
|
||||||
|
{ text: 'Tag Matches...', value: 'TAG', icon: 'T' }
|
||||||
],
|
],
|
||||||
locales: [
|
locales: [
|
||||||
{ text: 'English', value: 'en' }
|
{ text: 'English', value: 'en' }
|
||||||
|
@ -59,6 +59,8 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
|
|||||||
isPrivate: false
|
isPrivate: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
pageArgs.tags = _.get(page, 'tags', [])
|
||||||
|
|
||||||
const injectCode = {
|
const injectCode = {
|
||||||
css: WIKI.config.theming.injectCSS,
|
css: WIKI.config.theming.injectCSS,
|
||||||
head: WIKI.config.theming.injectHead,
|
head: WIKI.config.theming.injectHead,
|
||||||
@ -109,17 +111,20 @@ router.get(['/h', '/h/*'], async (req, res, next) => {
|
|||||||
|
|
||||||
_.set(res, 'locals.siteConfig.lang', pageArgs.locale)
|
_.set(res, 'locals.siteConfig.lang', pageArgs.locale)
|
||||||
|
|
||||||
if (!WIKI.auth.checkAccess(req.user, ['read:history'], pageArgs)) {
|
|
||||||
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
|
||||||
return res.render('unauthorized', { action: 'history' })
|
|
||||||
}
|
|
||||||
|
|
||||||
const page = await WIKI.models.pages.getPageFromDb({
|
const page = await WIKI.models.pages.getPageFromDb({
|
||||||
path: pageArgs.path,
|
path: pageArgs.path,
|
||||||
locale: pageArgs.locale,
|
locale: pageArgs.locale,
|
||||||
userId: req.user.id,
|
userId: req.user.id,
|
||||||
isPrivate: false
|
isPrivate: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
pageArgs.tags = _.get(page, 'tags', [])
|
||||||
|
|
||||||
|
if (!WIKI.auth.checkAccess(req.user, ['read:history'], pageArgs)) {
|
||||||
|
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
||||||
|
return res.render('unauthorized', { action: 'history' })
|
||||||
|
}
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
_.set(res.locals, 'pageMeta.title', page.title)
|
_.set(res.locals, 'pageMeta.title', page.title)
|
||||||
_.set(res.locals, 'pageMeta.description', page.description)
|
_.set(res.locals, 'pageMeta.description', page.description)
|
||||||
@ -149,7 +154,8 @@ router.get(['/i', '/i/:id'], async (req, res, next) => {
|
|||||||
path: page.path,
|
path: page.path,
|
||||||
private: page.isPrivate,
|
private: page.isPrivate,
|
||||||
privateNS: page.privateNS,
|
privateNS: page.privateNS,
|
||||||
explicitLocale: false
|
explicitLocale: false,
|
||||||
|
tags: page.tags
|
||||||
})) {
|
})) {
|
||||||
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
||||||
return res.render('unauthorized', { action: 'view' })
|
return res.render('unauthorized', { action: 'view' })
|
||||||
@ -175,6 +181,14 @@ router.get(['/p', '/p/*'], (req, res, next) => {
|
|||||||
*/
|
*/
|
||||||
router.get(['/s', '/s/*'], async (req, res, next) => {
|
router.get(['/s', '/s/*'], async (req, res, next) => {
|
||||||
const pageArgs = pageHelper.parsePath(req.path, { stripExt: true })
|
const pageArgs = pageHelper.parsePath(req.path, { stripExt: true })
|
||||||
|
const page = await WIKI.models.pages.getPageFromDb({
|
||||||
|
path: pageArgs.path,
|
||||||
|
locale: pageArgs.locale,
|
||||||
|
userId: req.user.id,
|
||||||
|
isPrivate: false
|
||||||
|
})
|
||||||
|
|
||||||
|
pageArgs.tags = _.get(page, 'tags', [])
|
||||||
|
|
||||||
if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) {
|
if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) {
|
||||||
return res.redirect(`/s/${pageArgs.locale}/${pageArgs.path}`)
|
return res.redirect(`/s/${pageArgs.locale}/${pageArgs.path}`)
|
||||||
@ -186,12 +200,6 @@ router.get(['/s', '/s/*'], async (req, res, next) => {
|
|||||||
return res.render('unauthorized', { action: 'source' })
|
return res.render('unauthorized', { action: 'source' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = await WIKI.models.pages.getPageFromDb({
|
|
||||||
path: pageArgs.path,
|
|
||||||
locale: pageArgs.locale,
|
|
||||||
userId: req.user.id,
|
|
||||||
isPrivate: false
|
|
||||||
})
|
|
||||||
if (page) {
|
if (page) {
|
||||||
_.set(res.locals, 'pageMeta.title', page.title)
|
_.set(res.locals, 'pageMeta.title', page.title)
|
||||||
_.set(res.locals, 'pageMeta.description', page.description)
|
_.set(res.locals, 'pageMeta.description', page.description)
|
||||||
@ -224,14 +232,6 @@ router.get('/*', async (req, res, next) => {
|
|||||||
|
|
||||||
req.i18n.changeLanguage(pageArgs.locale)
|
req.i18n.changeLanguage(pageArgs.locale)
|
||||||
|
|
||||||
if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) {
|
|
||||||
if (pageArgs.path === 'home') {
|
|
||||||
return res.redirect('/login')
|
|
||||||
}
|
|
||||||
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
|
||||||
return res.status(403).render('unauthorized', { action: 'view' })
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const page = await WIKI.models.pages.getPage({
|
const page = await WIKI.models.pages.getPage({
|
||||||
path: pageArgs.path,
|
path: pageArgs.path,
|
||||||
@ -239,6 +239,17 @@ router.get('/*', async (req, res, next) => {
|
|||||||
userId: req.user.id,
|
userId: req.user.id,
|
||||||
isPrivate: false
|
isPrivate: false
|
||||||
})
|
})
|
||||||
|
pageArgs.tags = _.get(page, 'tags', [])
|
||||||
|
|
||||||
|
if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) {
|
||||||
|
if (pageArgs.path === 'home') {
|
||||||
|
return res.redirect('/login')
|
||||||
|
}
|
||||||
|
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
|
||||||
|
return res.status(403).render('unauthorized', {
|
||||||
|
action: 'view'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
_.set(res, 'locals.siteConfig.lang', pageArgs.locale)
|
_.set(res, 'locals.siteConfig.lang', pageArgs.locale)
|
||||||
|
|
||||||
|
@ -176,20 +176,31 @@ module.exports = {
|
|||||||
switch (rule.match) {
|
switch (rule.match) {
|
||||||
case 'START':
|
case 'START':
|
||||||
if (_.startsWith(`/${page.path}`, `/${rule.path}`)) {
|
if (_.startsWith(`/${page.path}`, `/${rule.path}`)) {
|
||||||
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['END', 'REGEX', 'EXACT'] })
|
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['END', 'REGEX', 'EXACT', 'TAG'] })
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'END':
|
case 'END':
|
||||||
if (_.endsWith(page.path, rule.path)) {
|
if (_.endsWith(page.path, rule.path)) {
|
||||||
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['REGEX', 'EXACT'] })
|
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['REGEX', 'EXACT', 'TAG'] })
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'REGEX':
|
case 'REGEX':
|
||||||
const reg = new RegExp(rule.path)
|
const reg = new RegExp(rule.path)
|
||||||
if (reg.test(page.path)) {
|
if (reg.test(page.path)) {
|
||||||
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['EXACT'] })
|
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['EXACT', 'TAG'] })
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'TAG':
|
||||||
|
_.get(page, 'tags', []).forEach(tag => {
|
||||||
|
if (tag.tag === rule.path) {
|
||||||
|
checkState = this._applyPageRuleSpecificity({
|
||||||
|
rule,
|
||||||
|
checkState,
|
||||||
|
higherPriority: ['EXACT']
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
case 'EXACT':
|
case 'EXACT':
|
||||||
if (`/${page.path}` === `/${rule.path}`) {
|
if (`/${page.path}` === `/${rule.path}`) {
|
||||||
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: [] })
|
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: [] })
|
||||||
|
@ -108,4 +108,5 @@ enum PageRuleMatch {
|
|||||||
EXACT
|
EXACT
|
||||||
END
|
END
|
||||||
REGEX
|
REGEX
|
||||||
|
TAG
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user