Fixed browser's timezone offset not being sent with the proper header
name ("minOffset" -> "minoffset").

Server will now actually think client is on UTC timezone if "minoffset"
header is unset.

Stricter "all" header check for uploads list API endpoint.
It will now only accept the header if set to "1" (string).

Fixed server error when either date: or expiry: keys get parsed as
empty strings.

"minoffset" header when listing uploads will now only be sent if
date: or expiry: keys are properly used (i.e. match expected patterns).

Updated filters help message about wrapping with double quotes when
specifying both date and time (since there will be a space in between).

Filters input will now have some automatic clean ups other than trims.
- Replace all tabs with whitespaces.
- Remove whitespaces after "<key>:".

Bumped v1 version string and rebuilt client assets.
This commit is contained in:
Bobby Wibowo 2020-05-24 08:28:54 +07:00
parent dab69e5882
commit 98b2f32ec5
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
5 changed files with 34 additions and 25 deletions

View File

@ -757,9 +757,9 @@ self.list = async (req, res) => {
const user = await utils.authorize(req, res) const user = await utils.authorize(req, res)
if (!user) return if (!user) return
const all = Boolean(req.headers.all) const all = req.headers.all === '1'
const filters = req.headers.filters const filters = req.headers.filters
const minoffset = req.headers.minoffset const minoffset = Number(req.headers.minoffset) || 0
const ismoderator = perms.is(user, 'moderator') const ismoderator = perms.is(user, 'moderator')
if (all && !ismoderator) if (all && !ismoderator)
return res.status(403).end() return res.status(403).end()
@ -947,7 +947,10 @@ self.list = async (req, res) => {
const match = date.match(/^(\d{4})?(\/\d{2})?(\/\d{2})?\s?(\d{2})?(:\d{2})?(:\d{2})?$/) const match = date.match(/^(\d{4})?(\/\d{2})?(\/\d{2})?\s?(\d{2})?(:\d{2})?(:\d{2})?$/)
if (match) { if (match) {
const offset = 60000 * (utils.timezoneOffset - minoffset) let offset = 0
if (minoffset !== undefined)
offset = 60000 * (utils.timezoneOffset - minoffset)
const dateObj = new Date(Date.now() + offset) const dateObj = new Date(Date.now() + offset)
if (match[1] !== undefined) if (match[1] !== undefined)
@ -964,8 +967,7 @@ self.list = async (req, res) => {
dateObj.setMilliseconds(0) dateObj.setMilliseconds(0)
// Calculate timezone differences // Calculate timezone differences
const newDateObj = new Date(dateObj.getTime() - offset) return new Date(dateObj.getTime() - offset)
return newDateObj
} else { } else {
return null return null
} }
@ -1163,7 +1165,7 @@ self.list = async (req, res) => {
// Then, refine using the supplied 'date' ranges // Then, refine using the supplied 'date' ranges
this.andWhere(function () { this.andWhere(function () {
if (!filterObj.queries.date) return if (!filterObj.queries.date || (!filterObj.queries.date.from && !filterObj.queries.date.to)) return
if (typeof filterObj.queries.date.from === 'number') if (typeof filterObj.queries.date.from === 'number')
if (typeof filterObj.queries.date.to === 'number') if (typeof filterObj.queries.date.to === 'number')
this.andWhereBetween('timestamp', [filterObj.queries.date.from, filterObj.queries.date.to]) this.andWhereBetween('timestamp', [filterObj.queries.date.from, filterObj.queries.date.to])
@ -1175,7 +1177,7 @@ self.list = async (req, res) => {
// Then, refine using the supplied 'expiry' ranges // Then, refine using the supplied 'expiry' ranges
this.andWhere(function () { this.andWhere(function () {
if (!filterObj.queries.expiry) return if (!filterObj.queries.expiry || (!filterObj.queries.expiry.from && !filterObj.queries.expiry.to)) return
if (typeof filterObj.queries.expiry.from === 'number') if (typeof filterObj.queries.expiry.from === 'number')
if (typeof filterObj.queries.expiry.to === 'number') if (typeof filterObj.queries.expiry.to === 'number')
this.andWhereBetween('expirydate', [filterObj.queries.expiry.from, filterObj.queries.expiry.to]) this.andWhereBetween('expirydate', [filterObj.queries.expiry.from, filterObj.queries.expiry.to])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -473,15 +473,19 @@ page.getUploads = (params = {}) => {
? `api/album/${params.album}/${params.pageNum}` ? `api/album/${params.album}/${params.pageNum}`
: `api/uploads/${params.pageNum}` : `api/uploads/${params.pageNum}`
const headers = { const headers = {}
all: params.all ? '1' : '',
filters: params.filters || ''
}
// Send client timezone offset if using filters if (params.all)
// Server will pretend client is on UTC if missing headers.all = '1'
if (headers.filters)
headers.minOffset = new Date().getTimezoneOffset() if (params.filters) {
headers.filters = params.filters
// Send client timezone offset if properly using date: and/or :expiry filters
// Server will pretend client is on UTC if unset
if (/(^|\s)(date|expiry):[\d"]/.test(params.filters))
headers.minoffset = new Date().getTimezoneOffset()
}
axios.get(url, { headers }).then(response => { axios.get(url, { headers }).then(response => {
if (response.data.success === false) if (response.data.success === false)
@ -1043,16 +1047,16 @@ page.uploadFiltersHelp = element => {
Negation sign can also be used to exclude the special case mentioned above (i.e. <code>-albumid:-</code>). Negation sign can also be used to exclude the special case mentioned above (i.e. <code>-albumid:-</code>).
`} `}
There are 2 range keys: <b>date</b> (upload date) and <b>expiry</b> (expiry date). There are 2 range keys: <b>date</b> (upload date) and <b>expiry</b> (expiry date).
Their format is: <code>YYYY/MM/DD HH:MM:SS-YYYY/MM/DD HH:MM:SS</code> ("from" date and "to" date respectively). Their format is: <code>"YYYY/MM/DD HH:MM:SS-YYYY/MM/DD HH:MM:SS"</code> ("from" date and "to" date respectively).
You may specify only one of the dates. You may specify only one of the dates.
If "to" date is missing, 'now' will be used. If "to" date is missing, 'now' will be used. If "from" date is missing, 'beginning of time' will be used.
If "from" date is missing, 'beginning of time' will be used.
If any of the subsequent date or time units are not specified, their first value will be used (e.g. January for month, 1 for day, and so on). If any of the subsequent date or time units are not specified, their first value will be used (e.g. January for month, 1 for day, and so on).
If only time is specified, today's date will be used. If only time is specified, today's date will be used.
In conclusion, the following examples are all valid: <code>date:2020/01/01 01:23-2018/01/01 06</code>, <code>expiry:-2020/05</code>, <code>date:12:34:56</code>. If you do not need to specify both date and time, you may omit the double quotes.
In conclusion, the following examples are all valid: <code>date:"2020/01/01 01:23-2018/01/01 06"</code>, <code>expiry:-2020/05</code>, <code>date:12:34:56</code>.
These keys can only be specified once each. These keys can only be specified once each.
<b>Timezone?</b> Don't fret, feel free to query the dates with your own timezone! <b>Timezone?</b> Feel free to query the dates with your own timezone.
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.
@ -1093,7 +1097,7 @@ page.uploadFiltersHelp = element => {
- Uploads uploaded since "1 June 2019 00:00:00": - Uploads uploaded since "1 June 2019 00:00:00":
<code>date:2019/06</code> <code>date:2019/06</code>
- Uploads uploaded between "7 April 2020 12:00:00" and "7 April 2020 23:59:59": - Uploads uploaded between "7 April 2020 12:00:00" and "7 April 2020 23:59:59":
<code>date:2020/04/07 12-2020/04/07 23:59:59</code> <code>date:"2020/04/07 12-2020/04/07 23:59:59"</code>
- Uploads uploaded before "5 February 2020 00:00:00": - Uploads uploaded before "5 February 2020 00:00:00":
<code>date:-2020/02/05</code> <code>date:-2020/02/05</code>
- Uploads which file names match "*.gz" but NOT "*.tar.gz": - Uploads which file names match "*.gz" but NOT "*.tar.gz":
@ -1117,7 +1121,10 @@ page.uploadFiltersHelp = element => {
} }
page.filterUploads = element => { page.filterUploads = element => {
const filters = document.querySelector(`#${element.dataset.filtersid || 'filters'}`).value.trim() const filters = document.querySelector(`#${element.dataset.filtersid || 'filters'}`).value
.trim()
.replace(/\t/g, ' ')
.replace(/(^|\s)((albumid|ip|user|date|expiry|is|sort|orderby):)\s+/g, '$2')
// eslint-disable-next-line compat/compat // eslint-disable-next-line compat/compat
page.getUploads(Object.assign(page.views[page.currentView], { page.getUploads(Object.assign(page.views[page.currentView], {
filters, filters,

View File

@ -1,5 +1,5 @@
{ {
"1": "1589665998", "1": "1590283732",
"2": "1589010026", "2": "1589010026",
"3": "1581416390", "3": "1581416390",
"4": "1581416390", "4": "1581416390",