mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-18 17:21:33 +00:00
Updated
* Replaced all instances of getElementById and getElementsByClassName with querySelector or querySelectorAll. * Updated utilsController.js to stop disabling no-async-promise-executor eslint rule. * Removed unused lines in dashboard.njk. * Refactored maxFileSize to maxSize in home.{css,js,njk}. * Updated ClamAV codes in lolisafe.js. No more pinging. Since querying version will also check connection anyway. * Option "Upload to album" in homepage is now selectable. Selecting this option will restore the uploader to not associate files with an album. * Fixed uploader to properly respect server's max file size. Also updated error message of file size to use MB instead of MiB. * Creating an album from homepage will automatically select the album. * Updated Dropzone.js to v5.5.0. * Bumped v1 & v3 version strings. * Various other small fixes.
This commit is contained in:
parent
14d69bf1c1
commit
3a398721b5
@ -16,8 +16,8 @@ const uploadsDir = path.join(__dirname, '..', config.uploads.folder)
|
||||
const chunkedUploads = Boolean(config.uploads.chunkSize)
|
||||
const chunksDir = path.join(uploadsDir, 'chunks')
|
||||
const maxSize = config.uploads.maxSize
|
||||
const maxSizeBytes = parseInt(maxSize) * 1000 * 1000
|
||||
const urlMaxSizeBytes = parseInt(config.uploads.urlMaxSize) * 1000 * 1000
|
||||
const maxSizeBytes = parseInt(maxSize) * 1e6
|
||||
const urlMaxSizeBytes = parseInt(config.uploads.urlMaxSize) * 1e6
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
destination (req, file, cb) {
|
||||
@ -181,11 +181,12 @@ uploadsController.actuallyUpload = async (req, res, user, albumid) => {
|
||||
|
||||
upload(req, res, async error => {
|
||||
if (error) {
|
||||
const expected = [
|
||||
// Suppress error logging for errors with these codes
|
||||
const suppress = [
|
||||
'LIMIT_FILE_SIZE',
|
||||
'LIMIT_UNEXPECTED_FILE'
|
||||
]
|
||||
if (expected.includes(error.code)) return erred(error.toString())
|
||||
if (error.code && suppress.includes(error.code)) return erred(error.toString())
|
||||
return erred(error)
|
||||
}
|
||||
|
||||
|
@ -298,16 +298,14 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => {
|
||||
const failed = []
|
||||
const ismoderator = perms.is(user, 'moderator')
|
||||
await Promise.all(chunks.map((chunk, index) => {
|
||||
// It's much too dirty to code the function below without async function
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const job = async () => {
|
||||
try {
|
||||
const files = await db.table('files')
|
||||
.whereIn(field, chunk)
|
||||
.where(function () {
|
||||
if (!ismoderator)
|
||||
this.where('userid', user.id)
|
||||
})
|
||||
.catch(reject)
|
||||
|
||||
// Push files that could not be found in DB
|
||||
failed.push.apply(failed, chunk.filter(v => !files.find(file => file[field] === v)))
|
||||
@ -324,13 +322,12 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => {
|
||||
))
|
||||
|
||||
if (!deletedFiles.length)
|
||||
return resolve()
|
||||
return true
|
||||
|
||||
// Delete all found files from database
|
||||
const deletedFromDb = await db.table('files')
|
||||
.whereIn('id', deletedFiles.map(file => file.id))
|
||||
.del()
|
||||
.catch(reject)
|
||||
|
||||
if (set)
|
||||
deletedFiles.forEach(file => {
|
||||
@ -360,9 +357,11 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => {
|
||||
if (result.errors.length)
|
||||
result.errors.forEach(error => console.error(`CF: ${error}`))
|
||||
})
|
||||
|
||||
return resolve()
|
||||
}).catch(console.error)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
return new Promise(resolve => job().then(() => resolve()))
|
||||
}))
|
||||
return failed
|
||||
}
|
||||
|
21
lolisafe.js
21
lolisafe.js
@ -166,22 +166,23 @@ const start = async () => {
|
||||
|
||||
const scan = config.uploads.scan
|
||||
if (scan && scan.enabled) {
|
||||
const created = await new Promise(async (resolve, reject) => {
|
||||
const createScanner = async () => {
|
||||
try {
|
||||
if (!scan.ip || !scan.port)
|
||||
return reject(new Error('clamd IP or port is missing'))
|
||||
throw new Error('clamd IP or port is missing')
|
||||
|
||||
const ping = await clamd.ping(scan.ip, scan.port).catch(reject)
|
||||
if (!ping)
|
||||
return reject(new Error('Could not ping clamd'))
|
||||
|
||||
const version = await clamd.version(scan.ip, scan.port).catch(reject)
|
||||
const version = await clamd.version(scan.ip, scan.port)
|
||||
console.log(`${scan.ip}:${scan.port} ${version}`)
|
||||
|
||||
const scanner = clamd.createScanner(scan.ip, scan.port)
|
||||
safe.set('clam-scanner', scanner)
|
||||
return resolve(true)
|
||||
}).catch(error => console.error(error.toString()))
|
||||
if (!created) return process.exit(1)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error(`ClamAV: ${error.toString()}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (!await createScanner()) return process.exit(1)
|
||||
}
|
||||
|
||||
if (config.uploads.cacheFileIdentifiers) {
|
||||
|
@ -33,7 +33,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#maxFileSize {
|
||||
#maxSize {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ page.getPrettyBytes = function (num, si) {
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
const elements = document.getElementsByClassName('file-size')
|
||||
const elements = document.querySelectorAll('.file-size')
|
||||
for (let i = 0; i < elements.length; i++)
|
||||
elements[i].innerHTML = page.getPrettyBytes(parseInt(elements[i].innerHTML.replace(/\s*B$/i, '')))
|
||||
|
||||
|
@ -56,19 +56,19 @@ page.verify = function () {
|
||||
window.onload = function () {
|
||||
page.verify()
|
||||
|
||||
page.user = document.getElementById('user')
|
||||
page.pass = document.getElementById('pass')
|
||||
page.user = document.querySelector('#user')
|
||||
page.pass = document.querySelector('#pass')
|
||||
|
||||
// Prevent default form's submit action
|
||||
document.getElementById('authForm').addEventListener('submit', function (event) {
|
||||
document.querySelector('#authForm').addEventListener('submit', function (event) {
|
||||
event.preventDefault()
|
||||
})
|
||||
|
||||
document.getElementById('loginBtn').addEventListener('click', function () {
|
||||
document.querySelector('#loginBtn').addEventListener('click', function () {
|
||||
page.do('login')
|
||||
})
|
||||
|
||||
document.getElementById('registerBtn').addEventListener('click', function () {
|
||||
document.querySelector('#registerBtn').addEventListener('click', function () {
|
||||
page.do('register')
|
||||
})
|
||||
}
|
||||
|
@ -115,14 +115,13 @@ page.verifyToken = function (token, reloadOnError) {
|
||||
}
|
||||
|
||||
page.prepareDashboard = function () {
|
||||
page.dom = document.getElementById('page')
|
||||
page.dom = document.querySelector('#page')
|
||||
page.dom.addEventListener('click', page.domClick, true)
|
||||
|
||||
// document.getElementById('auth').style.display = 'none'
|
||||
document.getElementById('dashboard').style.display = 'block'
|
||||
document.querySelector('#dashboard').style.display = 'block'
|
||||
|
||||
if (page.permissions.moderator) {
|
||||
const itemManageUploads = document.getElementById('itemManageUploads')
|
||||
const itemManageUploads = document.querySelector('#itemManageUploads')
|
||||
itemManageUploads.removeAttribute('disabled')
|
||||
itemManageUploads.addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
@ -131,14 +130,14 @@ page.prepareDashboard = function () {
|
||||
}
|
||||
|
||||
if (page.permissions.admin) {
|
||||
const itemServerStats = document.getElementById('itemServerStats')
|
||||
const itemServerStats = document.querySelector('#itemServerStats')
|
||||
itemServerStats.removeAttribute('disabled')
|
||||
itemServerStats.addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.getServerStats()
|
||||
})
|
||||
|
||||
const itemManageUsers = document.getElementById('itemManageUsers')
|
||||
const itemManageUsers = document.querySelector('#itemManageUsers')
|
||||
itemManageUsers.removeAttribute('disabled')
|
||||
itemManageUsers.addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
@ -146,37 +145,37 @@ page.prepareDashboard = function () {
|
||||
})
|
||||
}
|
||||
|
||||
document.getElementById('itemUploads').addEventListener('click', function () {
|
||||
document.querySelector('#itemUploads').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.getUploads({ all: false })
|
||||
})
|
||||
|
||||
document.getElementById('itemDeleteByNames').addEventListener('click', function () {
|
||||
document.querySelector('#itemDeleteByNames').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.deleteByNames()
|
||||
})
|
||||
|
||||
document.getElementById('itemManageGallery').addEventListener('click', function () {
|
||||
document.querySelector('#itemManageGallery').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.getAlbums()
|
||||
})
|
||||
|
||||
document.getElementById('itemFileLength').addEventListener('click', function () {
|
||||
document.querySelector('#itemFileLength').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.changeFileLength()
|
||||
})
|
||||
|
||||
document.getElementById('itemTokens').addEventListener('click', function () {
|
||||
document.querySelector('#itemTokens').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.changeToken()
|
||||
})
|
||||
|
||||
document.getElementById('itemPassword').addEventListener('click', function () {
|
||||
document.querySelector('#itemPassword').addEventListener('click', function () {
|
||||
page.setActiveMenu(this)
|
||||
page.changePassword()
|
||||
})
|
||||
|
||||
const logoutBtn = document.getElementById('itemLogout')
|
||||
const logoutBtn = document.querySelector('#itemLogout')
|
||||
logoutBtn.addEventListener('click', function () {
|
||||
page.logout()
|
||||
})
|
||||
@ -315,13 +314,14 @@ page.switchPage = function (action, element) {
|
||||
case 'page-goto':
|
||||
views.pageNum = parseInt(element.dataset.goto)
|
||||
return func(views, element)
|
||||
case 'jump-to-page':
|
||||
const jumpToPage = parseInt(document.getElementById('jumpToPage').value)
|
||||
case 'jump-to-page': {
|
||||
const jumpToPage = parseInt(document.querySelector('#jumpToPage').value)
|
||||
views.pageNum = isNaN(jumpToPage) ? 0 : (jumpToPage - 1)
|
||||
if (views.pageNum < 0) views.pageNum = 0
|
||||
return func(views, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page.getUploads = function ({ pageNum, album, all, filters } = {}, element) {
|
||||
if (element) page.isLoading(element, true)
|
||||
@ -480,7 +480,7 @@ page.getUploads = function ({ pageNum, album, all, filters } = {}, element) {
|
||||
`
|
||||
page.fadeIn()
|
||||
|
||||
const table = document.getElementById('table')
|
||||
const table = document.querySelector('#table')
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const upload = files[i]
|
||||
@ -553,7 +553,7 @@ page.getUploads = function ({ pageNum, album, all, filters } = {}, element) {
|
||||
`
|
||||
page.fadeIn()
|
||||
|
||||
const table = document.getElementById('table')
|
||||
const table = document.querySelector('#table')
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const upload = files[i]
|
||||
@ -597,7 +597,7 @@ page.getUploads = function ({ pageNum, album, all, filters } = {}, element) {
|
||||
}
|
||||
|
||||
if (allSelected && files.length) {
|
||||
const selectAll = document.getElementById('selectAll')
|
||||
const selectAll = document.querySelector('#selectAll')
|
||||
if (selectAll) selectAll.checked = true
|
||||
}
|
||||
|
||||
@ -771,7 +771,7 @@ page.clearSelection = function () {
|
||||
localStorage[lsKeys.selected[page.currentView]] = '[]'
|
||||
page.selected[page.currentView] = []
|
||||
|
||||
const selectAll = document.getElementById('selectAll')
|
||||
const selectAll = document.querySelector('#selectAll')
|
||||
if (selectAll) selectAll.checked = false
|
||||
|
||||
return swal('Cleared selection!', `Unselected ${count} ${suffix}.`, 'success')
|
||||
@ -809,14 +809,14 @@ page.filtersHelp = function (element) {
|
||||
}
|
||||
|
||||
page.filterUploads = function (element) {
|
||||
const filters = document.getElementById('filters').value
|
||||
const filters = document.querySelector('#filters').value
|
||||
page.getUploads({ all: true, filters }, element)
|
||||
}
|
||||
|
||||
page.viewUserUploads = function (id) {
|
||||
const user = page.cache.users[id]
|
||||
if (!user) return
|
||||
page.setActiveMenu(document.getElementById('itemManageUploads'))
|
||||
page.setActiveMenu(document.querySelector('#itemManageUploads'))
|
||||
page.getUploads({ all: true, filters: `user:${user.username.replace(/ /g, '\\ ')}` })
|
||||
}
|
||||
|
||||
@ -944,7 +944,7 @@ page.deleteByNames = function () {
|
||||
}
|
||||
|
||||
page.deleteFileByNames = function () {
|
||||
const names = document.getElementById('names').value
|
||||
const names = document.querySelector('#names').value
|
||||
.split(/\r?\n/)
|
||||
.filter(function (n) {
|
||||
return n.trim().length
|
||||
@ -986,7 +986,7 @@ page.deleteFileByNames = function () {
|
||||
if (bulkdelete.data.failed && bulkdelete.data.failed.length)
|
||||
deleted -= bulkdelete.data.failed.length
|
||||
|
||||
document.getElementById('names').value = bulkdelete.data.failed.join('\n')
|
||||
document.querySelector('#names').value = bulkdelete.data.failed.join('\n')
|
||||
swal('Deleted!', `${deleted} file${deleted === 1 ? ' has' : 's have'} been deleted.`, 'success')
|
||||
}).catch(function (error) {
|
||||
console.log(error)
|
||||
@ -1058,7 +1058,7 @@ page.addFilesToAlbum = function (ids, callback) {
|
||||
}).then(function (choose) {
|
||||
if (!choose) return
|
||||
|
||||
const albumid = parseInt(document.getElementById('swalAlbum').value)
|
||||
const albumid = parseInt(document.querySelector('#swalAlbum').value)
|
||||
if (isNaN(albumid))
|
||||
return swal('An error occurred!', 'You did not choose an album.', 'error')
|
||||
|
||||
@ -1107,7 +1107,7 @@ page.addFilesToAlbum = function (ids, callback) {
|
||||
return
|
||||
}
|
||||
|
||||
const select = document.getElementById('swalAlbum')
|
||||
const select = document.querySelector('#swalAlbum')
|
||||
// If the prompt was replaced, the container would be missing
|
||||
if (!select) return
|
||||
select.innerHTML += list.data.albums
|
||||
@ -1180,7 +1180,7 @@ page.getAlbums = function () {
|
||||
page.fadeIn()
|
||||
|
||||
const homeDomain = response.data.homeDomain
|
||||
const table = document.getElementById('table')
|
||||
const table = document.querySelector('#table')
|
||||
|
||||
for (let i = 0; i < response.data.albums.length; i++) {
|
||||
const album = response.data.albums[i]
|
||||
@ -1292,11 +1292,11 @@ page.editAlbum = function (id) {
|
||||
|
||||
axios.post('api/albums/edit', {
|
||||
id,
|
||||
name: document.getElementById('swalName').value,
|
||||
description: document.getElementById('swalDescription').value,
|
||||
download: document.getElementById('swalDownload').checked,
|
||||
public: document.getElementById('swalPublic').checked,
|
||||
requestLink: document.getElementById('swalRequestLink').checked
|
||||
name: document.querySelector('#swalName').value,
|
||||
description: document.querySelector('#swalDescription').value,
|
||||
download: document.querySelector('#swalDownload').checked,
|
||||
public: document.querySelector('#swalPublic').checked,
|
||||
requestLink: document.querySelector('#swalRequestLink').checked
|
||||
}).then(function (response) {
|
||||
if (!response) return
|
||||
|
||||
@ -1370,8 +1370,8 @@ page.submitAlbum = function (element) {
|
||||
page.isLoading(element, true)
|
||||
|
||||
axios.post('api/albums', {
|
||||
name: document.getElementById('albumName').value,
|
||||
description: document.getElementById('albumDescription').value
|
||||
name: document.querySelector('#albumName').value,
|
||||
description: document.querySelector('#albumDescription').value
|
||||
}).then(function (response) {
|
||||
if (!response) return
|
||||
|
||||
@ -1405,7 +1405,7 @@ page.getAlbumsSidebar = function () {
|
||||
return swal('An error occurred!', response.data.description, 'error')
|
||||
}
|
||||
|
||||
const albumsContainer = document.getElementById('albumsContainer')
|
||||
const albumsContainer = document.querySelector('#albumsContainer')
|
||||
albumsContainer.innerHTML = ''
|
||||
|
||||
if (response.data.albums === undefined) return
|
||||
@ -1473,8 +1473,8 @@ page.changeFileLength = function () {
|
||||
`
|
||||
page.fadeIn()
|
||||
|
||||
document.getElementById('setFileLength').addEventListener('click', function () {
|
||||
page.setFileLength(document.getElementById('fileLength').value, this)
|
||||
document.querySelector('#setFileLength').addEventListener('click', function () {
|
||||
page.setFileLength(document.querySelector('#fileLength').value, this)
|
||||
})
|
||||
}).catch(function (error) {
|
||||
console.log(error)
|
||||
@ -1604,9 +1604,9 @@ page.changePassword = function () {
|
||||
`
|
||||
page.fadeIn()
|
||||
|
||||
document.getElementById('sendChangePassword').addEventListener('click', function () {
|
||||
if (document.getElementById('password').value === document.getElementById('passwordConfirm').value)
|
||||
page.sendNewPassword(document.getElementById('password').value, this)
|
||||
document.querySelector('#sendChangePassword').addEventListener('click', function () {
|
||||
if (document.querySelector('#password').value === document.querySelector('#passwordConfirm').value)
|
||||
page.sendNewPassword(document.querySelector('#password').value, this)
|
||||
else
|
||||
swal({
|
||||
title: 'Password mismatch!',
|
||||
@ -1644,7 +1644,7 @@ page.sendNewPassword = function (pass, element) {
|
||||
}
|
||||
|
||||
page.setActiveMenu = function (activeItem) {
|
||||
const menu = document.getElementById('menu')
|
||||
const menu = document.querySelector('#menu')
|
||||
const items = menu.getElementsByTagName('a')
|
||||
for (let i = 0; i < items.length; i++)
|
||||
items[i].classList.remove('is-active')
|
||||
@ -1753,7 +1753,7 @@ page.getUsers = function ({ pageNum } = {}, element) {
|
||||
`
|
||||
page.fadeIn()
|
||||
|
||||
const table = document.getElementById('table')
|
||||
const table = document.querySelector('#table')
|
||||
|
||||
for (let i = 0; i < response.data.users.length; i++) {
|
||||
const user = response.data.users[i]
|
||||
@ -1810,12 +1810,11 @@ page.getUsers = function ({ pageNum } = {}, element) {
|
||||
`
|
||||
|
||||
table.appendChild(tr)
|
||||
// page.checkboxes.users = Array.from(table.getElementsByClassName('checkbox'))
|
||||
page.checkboxes.users = Array.from(table.querySelectorAll('.checkbox[data-action="select"]'))
|
||||
}
|
||||
|
||||
if (allSelected && response.data.users.length) {
|
||||
const selectAll = document.getElementById('selectAll')
|
||||
const selectAll = document.querySelector('#selectAll')
|
||||
if (selectAll) selectAll.checked = true
|
||||
}
|
||||
|
||||
@ -1888,10 +1887,10 @@ page.editUser = function (id) {
|
||||
|
||||
axios.post('api/users/edit', {
|
||||
id,
|
||||
username: document.getElementById('swalUsername').value,
|
||||
group: document.getElementById('swalGroup').value,
|
||||
enabled: document.getElementById('swalEnabled').checked,
|
||||
resetPassword: document.getElementById('swalResetPassword').checked
|
||||
username: document.querySelector('#swalUsername').value,
|
||||
group: document.querySelector('#swalGroup').value,
|
||||
enabled: document.querySelector('#swalEnabled').checked,
|
||||
resetPassword: document.querySelector('#swalResetPassword').checked
|
||||
}).then(function (response) {
|
||||
if (!response) return
|
||||
|
||||
|
@ -7,7 +7,7 @@ const page = {
|
||||
// configs from api/check
|
||||
private: null,
|
||||
enableUserAccounts: null,
|
||||
maxFileSize: null,
|
||||
maxSize: null,
|
||||
chunkSize: null,
|
||||
|
||||
// store album id that will be used with upload requests
|
||||
@ -27,12 +27,12 @@ page.checkIfPublic = function () {
|
||||
axios.get('api/check').then(function (response) {
|
||||
page.private = response.data.private
|
||||
page.enableUserAccounts = response.data.enableUserAccounts
|
||||
page.maxFileSize = response.data.maxFileSize
|
||||
page.maxSize = response.data.maxSize
|
||||
page.chunkSize = response.data.chunkSize
|
||||
page.preparePage()
|
||||
}).catch(function (error) {
|
||||
console.log(error)
|
||||
const button = document.getElementById('loginToUpload')
|
||||
const button = document.querySelector('#loginToUpload')
|
||||
button.classList.remove('is-loading')
|
||||
button.innerText = 'Error occurred. Reload the page?'
|
||||
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
|
||||
@ -44,7 +44,7 @@ page.preparePage = function () {
|
||||
if (page.token) {
|
||||
return page.verifyToken(page.token, true)
|
||||
} else {
|
||||
const button = document.getElementById('loginToUpload')
|
||||
const button = document.querySelector('#loginToUpload')
|
||||
button.href = 'auth'
|
||||
button.classList.remove('is-loading')
|
||||
|
||||
@ -84,7 +84,7 @@ page.verifyToken = function (token, reloadOnError) {
|
||||
page.prepareUpload = function () {
|
||||
// I think this fits best here because we need to check for a valid token before we can get the albums
|
||||
if (page.token) {
|
||||
page.albumSelect = document.getElementById('albumSelect')
|
||||
page.albumSelect = document.querySelector('#albumSelect')
|
||||
|
||||
page.albumSelect.addEventListener('change', function () {
|
||||
page.album = parseInt(page.albumSelect.value)
|
||||
@ -93,14 +93,14 @@ page.prepareUpload = function () {
|
||||
page.prepareAlbums()
|
||||
|
||||
// Display the album selection
|
||||
document.getElementById('albumDiv').style.display = 'flex'
|
||||
document.querySelector('#albumDiv').style.display = 'flex'
|
||||
}
|
||||
|
||||
document.getElementById('maxFileSize').innerHTML = `Maximum upload size per file is ${page.maxFileSize}`
|
||||
document.getElementById('loginToUpload').style.display = 'none'
|
||||
document.querySelector('#maxSize').innerHTML = `Maximum upload size per file is ${page.maxSize}`
|
||||
document.querySelector('#loginToUpload').style.display = 'none'
|
||||
|
||||
if (!page.token && page.enableUserAccounts)
|
||||
document.getElementById('loginLinkText').innerHTML = 'Create an account and keep track of your uploads'
|
||||
document.querySelector('#loginLinkText').innerHTML = 'Create an account and keep track of your uploads'
|
||||
|
||||
const previewNode = document.querySelector('#tpl')
|
||||
page.previewTemplate = previewNode.innerHTML
|
||||
@ -108,7 +108,7 @@ page.prepareUpload = function () {
|
||||
|
||||
page.prepareDropzone()
|
||||
|
||||
const tabs = document.getElementById('tabs')
|
||||
const tabs = document.querySelector('#tabs')
|
||||
if (tabs) {
|
||||
tabs.style.display = 'flex'
|
||||
const items = tabs.getElementsByTagName('li')
|
||||
@ -117,12 +117,12 @@ page.prepareUpload = function () {
|
||||
page.setActiveTab(this.dataset.id)
|
||||
})
|
||||
|
||||
document.getElementById('uploadUrls').addEventListener('click', function () {
|
||||
document.querySelector('#uploadUrls').addEventListener('click', function () {
|
||||
page.uploadUrls(this)
|
||||
})
|
||||
page.setActiveTab('tab-files')
|
||||
} else {
|
||||
document.getElementById('tab-files').style.display = 'block'
|
||||
document.querySelector('#tab-files').style.display = 'block'
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,6 @@ page.prepareAlbums = function () {
|
||||
const option = document.createElement('option')
|
||||
option.value = ''
|
||||
option.innerHTML = 'Upload to album'
|
||||
option.disabled = true
|
||||
option.selected = true
|
||||
page.albumSelect.appendChild(option)
|
||||
|
||||
@ -164,7 +163,7 @@ page.prepareAlbums = function () {
|
||||
}
|
||||
|
||||
page.setActiveTab = function (activeId) {
|
||||
const items = document.getElementById('tabs').getElementsByTagName('li')
|
||||
const items = document.querySelector('#tabs').getElementsByTagName('li')
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const tabId = items[i].dataset.id
|
||||
if (tabId === activeId) {
|
||||
@ -178,7 +177,7 @@ page.setActiveTab = function (activeId) {
|
||||
}
|
||||
|
||||
page.prepareDropzone = function () {
|
||||
const tabDiv = document.getElementById('tab-files')
|
||||
const tabDiv = document.querySelector('#tab-files')
|
||||
const div = document.createElement('div')
|
||||
div.className = 'control is-expanded'
|
||||
div.innerHTML = `
|
||||
@ -191,28 +190,31 @@ page.prepareDropzone = function () {
|
||||
`
|
||||
tabDiv.querySelector('.dz-container').appendChild(div)
|
||||
|
||||
const maxSize = parseInt(page.maxSize)
|
||||
const maxSizeBytes = maxSize * 1e6
|
||||
|
||||
const previewsContainer = tabDiv.querySelector('#tab-files .field.uploads')
|
||||
|
||||
page.dropzone = new Dropzone('#dropzone', {
|
||||
url: 'api/upload',
|
||||
paramName: 'files[]',
|
||||
maxFilesize: parseInt(page.maxFileSize),
|
||||
maxFilesize: maxSizeBytes / 1024 / 1024, // this option expects MiB
|
||||
parallelUploads: 2,
|
||||
uploadMultiple: false,
|
||||
previewsContainer,
|
||||
previewTemplate: page.previewTemplate,
|
||||
createImageThumbnails: false,
|
||||
maxFiles: 1000,
|
||||
autoProcessQueue: true,
|
||||
headers: { token: page.token },
|
||||
chunking: Boolean(page.chunkSize),
|
||||
chunkSize: parseInt(page.chunkSize) * 1000000, // 1000000 B = 1 MB,
|
||||
parallelChunkUploads: false, // when set to true, sometimes it often hangs with hundreds of parallel uploads
|
||||
chunkSize: (parseInt(page.chunkSize) * 1e6), // the option below expects Bytes
|
||||
parallelChunkUploads: false, // when set to true, it often hangs with hundreds of parallel uploads
|
||||
chunksUploaded (file, done) {
|
||||
file.previewElement.querySelector('.progress').setAttribute('value', 100)
|
||||
file.previewElement.querySelector('.progress').innerHTML = '100%'
|
||||
|
||||
return axios.post('api/upload/finishchunks', {
|
||||
// The API supports an array of multiple files
|
||||
// This API supports an array of multiple files
|
||||
files: [{
|
||||
uuid: file.upload.uuid,
|
||||
original: file.name,
|
||||
@ -245,7 +247,7 @@ page.prepareDropzone = function () {
|
||||
})
|
||||
|
||||
page.dropzone.on('addedfile', function (file) {
|
||||
tabDiv.getElementsByClassName('uploads')[0].style.display = 'block'
|
||||
tabDiv.querySelector('.uploads').style.display = 'block'
|
||||
file.previewElement.querySelector('.name').innerHTML = file.name
|
||||
})
|
||||
|
||||
@ -257,6 +259,8 @@ page.prepareDropzone = function () {
|
||||
|
||||
// Update the total progress bar
|
||||
page.dropzone.on('uploadprogress', function (file, progress) {
|
||||
// For some reason, chunked uploads fire 100% progress event
|
||||
// for each chunk's successful uploads
|
||||
if (file.upload.chunked && progress === 100) return
|
||||
file.previewElement.querySelector('.progress').setAttribute('value', progress)
|
||||
file.previewElement.querySelector('.progress').innerHTML = `${progress}%`
|
||||
@ -265,7 +269,6 @@ page.prepareDropzone = function () {
|
||||
page.dropzone.on('success', function (file, response) {
|
||||
if (!response) return
|
||||
file.previewElement.querySelector('.progress').style.display = 'none'
|
||||
// file.previewElement.querySelector('.name').innerHTML = file.name
|
||||
|
||||
if (response.success === false)
|
||||
file.previewElement.querySelector('.error').innerHTML = response.description
|
||||
@ -275,6 +278,9 @@ page.prepareDropzone = function () {
|
||||
})
|
||||
|
||||
page.dropzone.on('error', function (file, error) {
|
||||
if ((typeof error === 'string' && /^File is too big/.test(error)) ||
|
||||
error.description === 'MulterError: File too large')
|
||||
error = `File too large (${(file.size / 1e6).toFixed(2)}MB).`
|
||||
page.updateTemplateIcon(file.previewElement, 'icon-block')
|
||||
file.previewElement.querySelector('.progress').style.display = 'none'
|
||||
file.previewElement.querySelector('.name').innerHTML = file.name
|
||||
@ -285,7 +291,7 @@ page.prepareDropzone = function () {
|
||||
}
|
||||
|
||||
page.uploadUrls = function (button) {
|
||||
const tabDiv = document.getElementById('tab-urls')
|
||||
const tabDiv = document.querySelector('#tab-urls')
|
||||
if (!tabDiv) return
|
||||
|
||||
if (button.classList.contains('is-loading')) return
|
||||
@ -298,19 +304,19 @@ page.uploadUrls = function (button) {
|
||||
|
||||
function run () {
|
||||
const albumid = page.album
|
||||
const previewsContainer = tabDiv.getElementsByClassName('uploads')[0]
|
||||
const urls = document.getElementById('urls').value
|
||||
const previewsContainer = tabDiv.querySelector('.uploads')
|
||||
const urls = document.querySelector('#urls').value
|
||||
.split(/\r?\n/)
|
||||
.filter(function (url) {
|
||||
return url.trim().length
|
||||
})
|
||||
document.getElementById('urls').value = urls.join('\n')
|
||||
document.querySelector('#urls').value = urls.join('\n')
|
||||
|
||||
if (!urls.length)
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
return done('You have not entered any URLs.')
|
||||
|
||||
tabDiv.getElementsByClassName('uploads')[0].style.display = 'block'
|
||||
tabDiv.querySelector('.uploads').style.display = 'block'
|
||||
const files = urls.map(function (url) {
|
||||
const previewTemplate = document.createElement('template')
|
||||
previewTemplate.innerHTML = page.previewTemplate.trim()
|
||||
@ -373,14 +379,14 @@ page.updateTemplate = function (file, response) {
|
||||
|
||||
const a = file.previewElement.querySelector('.link > a')
|
||||
const clipboard = file.previewElement.querySelector('.clipboard-mobile > .clipboard-js')
|
||||
a.href = a.innerHTML = clipboard.dataset['clipboardText'] = response.url
|
||||
a.href = a.innerHTML = clipboard.dataset.clipboardText = response.url
|
||||
clipboard.parentElement.style.display = 'block'
|
||||
|
||||
const exec = /.[\w]+(\?|$)/.exec(response.url)
|
||||
if (exec && exec[0] && page.imageExtensions.includes(exec[0].toLowerCase())) {
|
||||
const img = file.previewElement.querySelector('img')
|
||||
img.setAttribute('alt', response.name || '')
|
||||
img.dataset['src'] = response.url
|
||||
img.dataset.src = response.url
|
||||
img.style.display = ''
|
||||
img.onerror = function () {
|
||||
// Hide image elements that fail to load
|
||||
@ -438,12 +444,12 @@ page.createAlbum = function () {
|
||||
}).then(function (value) {
|
||||
if (!value) return
|
||||
|
||||
const name = document.getElementById('swalName').value
|
||||
const name = document.querySelector('#swalName').value
|
||||
axios.post('api/albums', {
|
||||
name,
|
||||
description: document.getElementById('swalDescription').value,
|
||||
download: document.getElementById('swalDownload').checked,
|
||||
public: document.getElementById('swalPublic').checked
|
||||
description: document.querySelector('#swalDescription').value,
|
||||
download: document.querySelector('#swalDownload').checked,
|
||||
public: document.querySelector('#swalPublic').checked
|
||||
}, {
|
||||
headers: {
|
||||
token: page.token
|
||||
@ -453,9 +459,10 @@ page.createAlbum = function () {
|
||||
return swal('An error occurred!', response.data.description, 'error')
|
||||
|
||||
const option = document.createElement('option')
|
||||
page.albumSelect.appendChild(option)
|
||||
option.value = response.data.id
|
||||
option.innerHTML = name
|
||||
page.albumSelect.appendChild(option)
|
||||
option.selected = true
|
||||
|
||||
swal('Woohoo!', 'Album was created successfully', 'success')
|
||||
}).catch(function (error) {
|
||||
@ -497,7 +504,7 @@ window.onload = function () {
|
||||
elements_selector: '.field.uploads img'
|
||||
})
|
||||
|
||||
document.getElementById('createAlbum').addEventListener('click', function () {
|
||||
document.querySelector('#createAlbum').addEventListener('click', function () {
|
||||
page.createAlbum()
|
||||
})
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ page.doRenderSwal = function () {
|
||||
}
|
||||
|
||||
page.getRenderVersion = function () {
|
||||
const renderScript = document.getElementById('renderScript')
|
||||
const renderScript = document.querySelector('#renderScript')
|
||||
if (renderScript && renderScript.dataset.version)
|
||||
return `?v=${renderScript.dataset.version}`
|
||||
return ''
|
||||
|
@ -4,7 +4,7 @@ page.prepareShareX = function () {
|
||||
if (!page.token) return
|
||||
const origin = (location.hostname + location.pathname).replace(/\/(dashboard)?$/, '')
|
||||
const originClean = origin.replace(/\//g, '_')
|
||||
const sharexElement = document.getElementById('ShareX')
|
||||
const sharexElement = document.querySelector('#ShareX')
|
||||
const sharexFile = `{
|
||||
"Name": "${originClean}",
|
||||
"DestinationType": "ImageUploader, FileUploader",
|
||||
|
4
public/libs/dropzone/dropzone.min.js
vendored
4
public/libs/dropzone/dropzone.min.js
vendored
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ routes.get('/check', (req, res, next) => {
|
||||
return res.json({
|
||||
private: config.private,
|
||||
enableUserAccounts: config.enableUserAccounts,
|
||||
maxFileSize: config.uploads.maxSize,
|
||||
maxSize: config.uploads.maxSize,
|
||||
chunkSize: config.uploads.chunkSize
|
||||
})
|
||||
})
|
||||
|
@ -16,9 +16,9 @@
|
||||
v3: CSS and JS files (libs such as bulma, lazyload, etc).
|
||||
v4: Renders in /public/render/* directories (to be used by render.js).
|
||||
#}
|
||||
{% set v1 = "S3TAWpPeFS" %}
|
||||
{% set v1 = "f0nYw5J15T" %}
|
||||
{% set v2 = "hiboQUzAzp" %}
|
||||
{% set v3 = "RpD2narcvz" %}
|
||||
{% set v3 = "f0nYw5J15T" %}
|
||||
{% set v4 = "S3TAWpPeFS" %}
|
||||
|
||||
{#
|
||||
|
@ -19,25 +19,6 @@
|
||||
|
||||
{% block content %}
|
||||
{{ super() }}
|
||||
{#
|
||||
<!-- This isn't even being used apparently -->
|
||||
<section id="auth" class="hero is-light is-fullheight">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<h1 class="title">
|
||||
Admin dashboard
|
||||
</h1>
|
||||
<h2 class="subtitle">
|
||||
<p class="control has-addons">
|
||||
<input id="token" class="input is-danger" type="text" placeholder="Your admin token">
|
||||
<a id="tokenSubmit" class="button is-danger is-outlined">Check</a>
|
||||
</p>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
#}
|
||||
|
||||
<section id="dashboard" class="section">
|
||||
<div id="panel" class="container">
|
||||
<h1 class="title">
|
||||
|
@ -38,7 +38,7 @@
|
||||
<h1 class="title">{{ globals.name }}</h1>
|
||||
<h2 class="subtitle">{{ globals.home_subtitle | safe }}</h2>
|
||||
|
||||
<h3 id="maxFileSize" class="subtitle"></h3>
|
||||
<h3 id="maxSize" class="subtitle"></h3>
|
||||
|
||||
<div class="columns is-gapless">
|
||||
<div class="column is-hidden-mobile"></div>
|
||||
|
Loading…
Reference in New Issue
Block a user