mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-19 01:31:34 +00:00
Added type-is filter keys (is:image and is:video)
Fixed text queries threshold being applied to moderators Bumped v1 version string and rebuilt client assets
This commit is contained in:
parent
d201b03f59
commit
126cfe0e15
@ -770,6 +770,7 @@ self.list = async (req, res) => {
|
|||||||
const MAX_WILDCARDS_IN_KEY = 2
|
const MAX_WILDCARDS_IN_KEY = 2
|
||||||
const MAX_TEXT_QUERIES = 3 // non-keyed keywords
|
const MAX_TEXT_QUERIES = 3 // non-keyed keywords
|
||||||
const MAX_SORT_KEYS = 1
|
const MAX_SORT_KEYS = 1
|
||||||
|
const MAX_IS_KEYS = 1
|
||||||
|
|
||||||
const filterObj = {
|
const filterObj = {
|
||||||
uploaders: [],
|
uploaders: [],
|
||||||
@ -777,6 +778,10 @@ self.list = async (req, res) => {
|
|||||||
queries: {
|
queries: {
|
||||||
exclude: {}
|
exclude: {}
|
||||||
},
|
},
|
||||||
|
typeIs: [
|
||||||
|
'image',
|
||||||
|
'video'
|
||||||
|
],
|
||||||
flags: {}
|
flags: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,6 +848,7 @@ self.list = async (req, res) => {
|
|||||||
|
|
||||||
filterObj.queries = searchQuery.parse(filters, {
|
filterObj.queries = searchQuery.parse(filters, {
|
||||||
keywords: keywords.concat([
|
keywords: keywords.concat([
|
||||||
|
'is',
|
||||||
'sort'
|
'sort'
|
||||||
]),
|
]),
|
||||||
ranges,
|
ranges,
|
||||||
@ -855,6 +861,7 @@ self.list = async (req, res) => {
|
|||||||
if (typeof filterObj.queries.exclude.text === 'string')
|
if (typeof filterObj.queries.exclude.text === 'string')
|
||||||
filterObj.queries.exclude.text = [filterObj.queries.exclude.text]
|
filterObj.queries.exclude.text = [filterObj.queries.exclude.text]
|
||||||
|
|
||||||
|
// Text (non-keyed keywords) queries
|
||||||
let textQueries = 0
|
let textQueries = 0
|
||||||
if (filterObj.queries.text) textQueries += filterObj.queries.text.length
|
if (filterObj.queries.text) textQueries += filterObj.queries.text.length
|
||||||
if (filterObj.queries.exclude.text) textQueries += filterObj.queries.exclude.text.length
|
if (filterObj.queries.exclude.text) textQueries += filterObj.queries.exclude.text.length
|
||||||
@ -869,7 +876,7 @@ self.list = async (req, res) => {
|
|||||||
if (filterObj.queries.text)
|
if (filterObj.queries.text)
|
||||||
for (let i = 0; i < filterObj.queries.text.length; i++) {
|
for (let i = 0; i < filterObj.queries.text.length; i++) {
|
||||||
const result = sqlLikeParser(filterObj.queries.text[i])
|
const result = sqlLikeParser(filterObj.queries.text[i])
|
||||||
if (result.count > MAX_WILDCARDS_IN_KEY)
|
if (!ismoderator && result.count > MAX_WILDCARDS_IN_KEY)
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
||||||
@ -877,18 +884,16 @@ self.list = async (req, res) => {
|
|||||||
filterObj.queries.text[i] = result.escaped
|
filterObj.queries.text[i] = result.escaped
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterObj.queries.exclude.text) {
|
if (filterObj.queries.exclude.text)
|
||||||
textQueries += filterObj.queries.exclude.text.length
|
|
||||||
for (let i = 0; i < filterObj.queries.exclude.text.length; i++) {
|
for (let i = 0; i < filterObj.queries.exclude.text.length; i++) {
|
||||||
const result = sqlLikeParser(filterObj.queries.exclude.text[i])
|
const result = sqlLikeParser(filterObj.queries.exclude.text[i])
|
||||||
if (result.count > MAX_WILDCARDS_IN_KEY)
|
if (!ismoderator && result.count > MAX_WILDCARDS_IN_KEY)
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
||||||
})
|
})
|
||||||
filterObj.queries.exclude.text[i] = result.escaped
|
filterObj.queries.exclude.text[i] = result.escaped
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (const key of keywords) {
|
for (const key of keywords) {
|
||||||
let queryIndex = -1
|
let queryIndex = -1
|
||||||
@ -1050,6 +1055,39 @@ self.list = async (req, res) => {
|
|||||||
// Delete key to avoid unexpected behavior
|
// Delete key to avoid unexpected behavior
|
||||||
delete filterObj.queries.sort
|
delete filterObj.queries.sort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse is keys
|
||||||
|
let isKeys = 0
|
||||||
|
let isLast
|
||||||
|
if (filterObj.queries.is || filterObj.queries.exclude.is) {
|
||||||
|
for (const type of filterObj.typeIs) {
|
||||||
|
const inQuery = filterObj.queries.is && filterObj.queries.is.includes(type)
|
||||||
|
const inExclude = filterObj.queries.exclude.is && filterObj.queries.exclude.is.includes(type)
|
||||||
|
|
||||||
|
// Prioritize exclude keys when both types found
|
||||||
|
if (inQuery || inExclude) {
|
||||||
|
filterObj.flags[`is${type}`] = inExclude ? false : inQuery
|
||||||
|
if (isLast !== undefined && isLast !== filterObj.flags[`is${type}`])
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
description: 'Cannot mix inclusion and exclusion type-is keys.'
|
||||||
|
})
|
||||||
|
isKeys++
|
||||||
|
isLast = filterObj.flags[`is${type}`]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete keys to avoid unexpected behavior
|
||||||
|
delete filterObj.queries.is
|
||||||
|
delete filterObj.queries.exclude.is
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular user threshold check
|
||||||
|
if (!ismoderator && isKeys > MAX_IS_KEYS)
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
description: `Users are only allowed to use ${MAX_IS_KEYS} type-is key${MAX_IS_KEYS === 1 ? '' : 's'} at a time.`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function filter () {
|
function filter () {
|
||||||
@ -1136,6 +1174,23 @@ self.list = async (req, res) => {
|
|||||||
this.andWhere('expirydate', '<=', filterObj.queries.date.to)
|
this.andWhere('expirydate', '<=', filterObj.queries.date.to)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Then, refine using type-is flags
|
||||||
|
this.andWhere(function () {
|
||||||
|
for (const type of filterObj.typeIs) {
|
||||||
|
const patterns = utils[`${type}Exts`].map(ext => `%${ext}`)
|
||||||
|
|
||||||
|
let operator
|
||||||
|
if (filterObj.flags[`is${type}`] === true)
|
||||||
|
operator = 'like'
|
||||||
|
else if (filterObj.flags[`is${type}`] === false)
|
||||||
|
operator = 'not like'
|
||||||
|
|
||||||
|
if (operator)
|
||||||
|
for (const pattern of patterns)
|
||||||
|
this.orWhere('name', operator, pattern)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Then, refine using the supplied keywords against their file names
|
// Then, refine using the supplied keywords against their file names
|
||||||
this.andWhere(function () {
|
this.andWhere(function () {
|
||||||
if (!filterObj.queries.text) return
|
if (!filterObj.queries.text) return
|
||||||
|
2
dist/js/dashboard.js
vendored
2
dist/js/dashboard.js
vendored
File diff suppressed because one or more lines are too long
2
dist/js/dashboard.js.map
vendored
2
dist/js/dashboard.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1049,13 +1049,19 @@ page.uploadFiltersHelp = element => {
|
|||||||
API requests to the filter endpoint will attach your browser's timezone offset, so the server will automatically calculate timezone differences.
|
API requests to the filter endpoint will attach your browser's timezone offset, so the server will automatically calculate timezone differences.
|
||||||
|
|
||||||
Matches can also be sorted with <b>sort</b> keys.
|
Matches can also be sorted with <b>sort</b> keys.
|
||||||
Its format is: <code>sort:columnName[:d[escending]]</code>, where <code>:d[escending]</code> is an optional tag to set the direction to descending.
|
Their formats are: <code>sort:columnName[:d[escending]]</code>, where <code>:d[escending]</code> is an optional tag to set the direction to descending.
|
||||||
This key must be used with internal column names used in the database (<code>id</code>, <code>${all ? 'userid' : 'albumid'}</code>, and so on),
|
This key must be used with internal column names used in the database (<code>id</code>, <code>${all ? 'userid' : 'albumid'}</code>, and so on),
|
||||||
but there are 2 shortcuts available: <b>date</b> for <code>timestamp</code> column and <b>expiry</b> for <code>expirydate</code> column.
|
but there are 2 shortcuts available: <b>date</b> for <code>timestamp</code> column and <b>expiry</b> for <code>expirydate</code> column.
|
||||||
This key can also be specified more than once, where their order will decide the sorting steps.
|
This key can also be specified more than once, where their order will decide the sorting steps.
|
||||||
|
|
||||||
|
Finally, there are type-<b>is</b> keys to refine by types.
|
||||||
|
You can use <code>is:image</code> and <code>is:video</code> to list images and videos respectively.
|
||||||
|
This will only use image/video extensions whose thumbnails can be generated by the safe.
|
||||||
|
Negation sign works for this key as well.
|
||||||
|
Mixing inclusion and exclusion is not allowed (i.e. <code>is:image -is:video</code>, since the second key is redundant).
|
||||||
|
|
||||||
Any leftover keywords which do not use keys (non-keyed keywords) will be matched against the matches' file names.
|
Any leftover keywords which do not use keys (non-keyed keywords) will be matched against the matches' file names.
|
||||||
Excluding certain keywords is also supported by adding negation sign (<b>-</b>) before the keywords.
|
Excluding certain keywords is also supported by adding negation sign before the keywords.
|
||||||
|
|
||||||
<b>Internal steps:</b>
|
<b>Internal steps:</b>
|
||||||
${all ? `- Query uploads passing ALL exclusion filter keys OR matching ANY filter keys, if any.
|
${all ? `- Query uploads passing ALL exclusion filter keys OR matching ANY filter keys, if any.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"1": "1588451242",
|
"1": "1588455082",
|
||||||
"2": "1581416390",
|
"2": "1581416390",
|
||||||
"3": "1581416390",
|
"3": "1581416390",
|
||||||
"4": "1581416390",
|
"4": "1581416390",
|
||||||
|
Loading…
Reference in New Issue
Block a user