diff --git a/.eslintrc.json b/.eslintrc.json index 20e31c2..60a330e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,15 +30,5 @@ "single" ], "no-var": "error" - }, - "overrides": [ - { - "files": [ - "public/**/*.js" - ], - "env": { - "browser": true - } - } - ] + } } diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..ce92a41 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,5 @@ +{ + "default": true, + "MD013": false, + "MD040": false +} diff --git a/README.md b/README.md index 0918cde..681afef 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,20 @@ If you want to use an existing lolisafe database with this branch, make sure to Configuration file of lolisafe, `config.js`, is also not 100% compatible with this branch. There are some options that had been renamed and/or restructured. Please make sure your config matches the sample in `config.sample.js` before starting. +## Missing thumbnails + +Thumbnails will not be automatically generated for files that have been uploaded prior to enabling thumbnails generation in the config file. To generate thumbnails for old files, you can try running `yarn thumbs` (a shortcut to running `node scripts/thumbs.js`). + +``` +Usage: +yarn thumbs [force=0|1] + +mode : 1 = images only, 2 = videos only, 3 = both images and videos +force: 0 = no force (default), 1 = overwrite existing thumbnails +``` + +For example, if you only want to generate thumbnails for image files, you can do `yarn thumbs 1`. + ## Running 1. Ensure you have at least version 8.0.0 of node installed diff --git a/controllers/albumsController.js b/controllers/albumsController.js index b32495d..cdbd7f6 100644 --- a/controllers/albumsController.js +++ b/controllers/albumsController.js @@ -138,7 +138,6 @@ albumsController.delete = async (req, res, next) => { return res.json({ success: false, description: 'No album specified.' }) } - let ids = [] let failed = [] if (purge) { const files = await db.table('files') @@ -147,11 +146,13 @@ albumsController.delete = async (req, res, next) => { userid: user.id }) - ids = files.map(file => file.id) - failed = await utils.bulkDeleteFiles('id', ids, user) + if (files.length) { + const ids = files.map(file => file.id) + failed = await utils.bulkDeleteFiles('id', ids, user) - if (failed.length === ids.length) { - return res.json({ success: false, description: 'Could not delete any of the files associated with the album.' }) + if (failed.length === ids.length) { + return res.json({ success: false, description: 'Could not delete any of the files associated with the album.' }) + } } } diff --git a/lolisafe.js b/lolisafe.js index 4d9a230..415c029 100644 --- a/lolisafe.js +++ b/lolisafe.js @@ -14,11 +14,11 @@ const safe = express() require('./database/db.js')(db) fs.existsSync('./pages/custom') || fs.mkdirSync('./pages/custom') -fs.existsSync('./' + config.logsFolder) || fs.mkdirSync('./' + config.logsFolder) -fs.existsSync('./' + config.uploads.folder) || fs.mkdirSync('./' + config.uploads.folder) -fs.existsSync('./' + config.uploads.folder + '/chunks') || fs.mkdirSync('./' + config.uploads.folder + '/chunks') -fs.existsSync('./' + config.uploads.folder + '/thumbs') || fs.mkdirSync('./' + config.uploads.folder + '/thumbs') -fs.existsSync('./' + config.uploads.folder + '/zips') || fs.mkdirSync('./' + config.uploads.folder + '/zips') +fs.existsSync(`./${config.logsFolder}`) || fs.mkdirSync(`./${config.logsFolder}`) +fs.existsSync(`./${config.uploads.folder}`) || fs.mkdirSync(`./${config.uploads.folder}`) +fs.existsSync(`./${config.uploads.folder}/chunks`) || fs.mkdirSync(`./${config.uploads.folder}/chunks`) +fs.existsSync(`./${config.uploads.folder}/thumbs`) || fs.mkdirSync(`./${config.uploads.folder}/thumbs`) +fs.existsSync(`./${config.uploads.folder}/zips`) || fs.mkdirSync(`./${config.uploads.folder}/zips`) safe.use(helmet()) safe.set('trust proxy', 1) diff --git a/package.json b/package.json index 8e44ecf..0d7a93d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "license": "MIT", "scripts": { "start": "node ./lolisafe.js", - "pm2": "pm2 start --name lolisafe ./lolisafe.js" + "pm2": "pm2 start --name lolisafe ./lolisafe.js", + "thumbs": "node ./scripts/thumbs.js" }, "dependencies": { "bcrypt": "^2.0.0", diff --git a/pages/error/README.md b/pages/error/README.md index 9da6919..7e8eaf5 100644 --- a/pages/error/README.md +++ b/pages/error/README.md @@ -1,5 +1,5 @@ -# Why do this folder only have symlinks? +# Disclaimer as to why this folder only have Symlinks -At safe.fiery.me, we are using this: [https://github.com/BobbyWibowo/HttpErrorPages](https://github.com/BobbyWibowo/HttpErrorPages). +At fiery.me, we are using this: [https://github.com/BobbyWibowo/HttpErrorPages](https://github.com/BobbyWibowo/HttpErrorPages). -It's nothing too important, but we are sharing the error pages from that directory to all other instances in the server. +It's nothing too important, but we are sharing the error pages from that directory to all other instances in the server (regular http sites with nginx and node servers). diff --git a/public/js/.eslintrc.json b/public/js/.eslintrc.json new file mode 100644 index 0000000..f9f4f2b --- /dev/null +++ b/public/js/.eslintrc.json @@ -0,0 +1,39 @@ +{ + "root": true, + "parserOptions": { + "ecmaVersion": 6 + }, + "env": { + "browser": true + }, + "extends": [ + "eslint:recommended" + ], + "rules": { + "curly": [ + "error", + "all" + ], + "no-console": 0, + "semi": [ + "error", + "never" + ], + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never", + "asyncArrow": "always" + } + ], + "quotes": [ + "error", + "single" + ], + "indent": [ + "error", + 2 + ] + } +} diff --git a/public/js/album.js b/public/js/album.js index 508cb55..7db04b0 100644 --- a/public/js/album.js +++ b/public/js/album.js @@ -1,7 +1,7 @@ /* global LazyLoad */ -const page = {} +var page = {} -window.onload = () => { +window.onload = function () { page.lazyLoad = new LazyLoad() } diff --git a/public/js/auth.js b/public/js/auth.js index 2d47b92..08acfaf 100644 --- a/public/js/auth.js +++ b/public/js/auth.js @@ -1,13 +1,22 @@ /* global swal, axios */ -const page = { +var page = { // user token - token: localStorage.token + token: localStorage.token, + + // HTML elements + user: null, + pass: null } -page.do = async dest => { - const user = document.getElementById('user').value - const pass = document.getElementById('pass').value +page.do = function (dest, onEnter) { + var user = page.user.value + var pass = page.pass.value + + // If the form is submitted with Enter button and the form is still empty + if (onEnter && !user.length && !pass.length) { return } + + console.log('page.do()\'ing: ' + dest) if (!user) { return swal('Error', 'You need to specify a username', 'error') @@ -17,51 +26,70 @@ page.do = async dest => { return swal('Error', 'You need to specify a username', 'error') } - const response = await axios.post(`api/${dest}`, { + axios.post(`api/${dest}`, { username: user, password: pass }) - .catch(error => { + .then(function (response) { + if (response.data.success === false) { + return swal('Error', response.data.description, 'error') + } + + localStorage.token = response.data.token + window.location = 'dashboard' + }) + .catch(function (error) { console.error(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - return swal('Error', response.data.description, 'error') - } - - localStorage.token = response.data.token - window.location = 'dashboard' } -page.verify = async () => { +page.verify = function () { if (!page.token) { return } - const response = await axios.post('api/tokens/verify', { + axios.post('api/tokens/verify', { token: page.token }) - .catch(error => { - console.error(error) - swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + .then(function (response) { + if (response.data.success === false) { + return swal('Error', response.data.description, 'error') + } + + window.location = 'dashboard' + }) + .catch(function (error) { + console.error(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - return swal('Error', response.data.description, 'error') - } - - window.location = 'dashboard' } -window.onload = () => { +page.formEnter = function (event) { + if (event.keyCode === 13 || event.which === 13) { + event.preventDefault() + event.stopPropagation() + page.do('login', true) + } +} + +window.onload = function () { page.verify() - document.body.addEventListener('keydown', event => { - event = event || window.event - if (!event) { return } - const id = event.target.id - if (!['user', 'pass'].includes(id)) { return } - if (event.keyCode === 13 || event.which === 13) { page.do('login') } + page.user = document.getElementById('user') + page.pass = document.getElementById('pass') + + var form = document.getElementById('authForm') + form.addEventListener('keyup', page.formEnter) + form.addEventListener('keypress', page.formEnter) + form.onsubmit = function (event) { + event.preventDefault() + event.stopPropagation() + } + + document.getElementById('loginBtn').addEventListener('click', function () { + page.do('login') + }) + + document.getElementById('registerBtn').addEventListener('click', function () { + page.do('register') }) } diff --git a/public/js/dashboard.js b/public/js/dashboard.js index e57fbcd..f48645e 100644 --- a/public/js/dashboard.js +++ b/public/js/dashboard.js @@ -1,6 +1,6 @@ /* global swal, axios, ClipboardJS, LazyLoad */ -const page = { +var page = { // #page dom: null, @@ -23,14 +23,14 @@ const page = { selectAlbumContainer: null, // cache of files and albums data for dialogs/modals - files: new Map(), - albums: new Map(), + files: {}, + albums: {}, clipboardJS: null, lazyLoad: null } -page.preparePage = () => { +page.preparePage = function () { if (!page.token) { window.location = 'auth' return @@ -38,272 +38,197 @@ page.preparePage = () => { page.verifyToken(page.token, true) } -page.verifyToken = async (token, reloadOnError = false) => { - const response = await axios.post('api/tokens/verify', { token }) - .catch(error => { +page.verifyToken = function (token, reloadOnError) { + axios.post('api/tokens/verify', { token }) + .then(function (response) { + if (response.data.success === false) { + return swal({ + title: 'An error occurred!', + text: response.data.description, + icon: 'error' + }) + .then(function () { + if (!reloadOnError) { return } + localStorage.removeItem('token') + location.location = 'auth' + }) + } + + axios.defaults.headers.common.token = token + localStorage.token = token + page.token = token + page.username = response.data.username + page.prepareDashboard() + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - await swal({ - title: 'An error occurred!', - text: response.data.description, - icon: 'error' - }) - if (reloadOnError) { - localStorage.removeItem('token') - location.location = 'auth' - } - return - } - - axios.defaults.headers.common.token = token - localStorage.token = token - page.token = token - page.username = response.data.username - page.prepareDashboard() } -page.prepareDashboard = () => { +page.prepareDashboard = function () { page.dom = document.getElementById('page') document.getElementById('auth').style.display = 'none' document.getElementById('dashboard').style.display = 'block' document.getElementById('itemUploads').addEventListener('click', function () { page.setActiveMenu(this) + page.getUploads() }) document.getElementById('itemDeleteByNames').addEventListener('click', function () { page.setActiveMenu(this) + page.deleteByNames() }) document.getElementById('itemManageGallery').addEventListener('click', function () { page.setActiveMenu(this) + page.getAlbums() }) document.getElementById('itemFileLength').addEventListener('click', function () { page.setActiveMenu(this) + page.changeFileLength() }) document.getElementById('itemTokens').addEventListener('click', function () { page.setActiveMenu(this) + page.changeToken() }) document.getElementById('itemPassword').addEventListener('click', function () { page.setActiveMenu(this) + page.changePassword() }) - document.getElementById('itemLogout').innerHTML = `Logout ( ${page.username} )` + var logoutBtn = document.getElementById('itemLogout') + logoutBtn.addEventListener('click', function () { + page.logout() + }) + logoutBtn.innerHTML = `Logout ( ${page.username} )` page.getAlbumsSidebar() } -page.logout = () => { +page.logout = function () { localStorage.removeItem('token') location.reload('.') } -page.isLoading = (element, state) => { +page.isLoading = function (element, state) { if (!element) { return } if (state) { return element.classList.add('is-loading') } element.classList.remove('is-loading') } -page.getUploads = async (album, pageNum, element) => { +page.getUploads = function (album, pageNum, element) { if (element) { page.isLoading(element, true) } if (pageNum === undefined) { pageNum = 0 } - let url = 'api/uploads/' + pageNum + var url = 'api/uploads/' + pageNum if (album !== undefined) { url = 'api/album/' + album + '/' + pageNum } - const response = await axios.get(url) - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') - }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - page.files.clear() - - let prevPage = 0 - let nextPage = pageNum + 1 - - if (response.data.files.length < 25) { nextPage = pageNum } - - if (pageNum > 0) { prevPage = pageNum - 1 } - - const pagination = ` - - ` - const controls = ` -
-
- - -
- ` - - let allFilesSelected = true - if (page.filesView === 'thumbs') { - page.dom.innerHTML = ` - ${pagination} -
- ${controls} -
- -
- ${pagination} - ` - - const table = document.getElementById('table') - - for (const file of response.data.files) { - const selected = page.selectedFiles.includes(file.id) - if (!selected && allFilesSelected) { allFilesSelected = false } - - const div = document.createElement('div') - - let displayAlbumOrUser = file.album - if (page.username === 'root') { - displayAlbumOrUser = '' - if (file.username !== undefined) { displayAlbumOrUser = file.username } + axios.get(url) + .then(function (response) { + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } } - div.className = 'image-container column is-narrow' - if (file.thumb !== undefined) { - div.innerHTML = `${file.name}` - } else { - div.innerHTML = `

${file.extname || 'N/A'}

` - } - div.innerHTML += ` - -
- - - - - - - - - - - - - - - -
-
-

${file.name}

-

${displayAlbumOrUser ? `${displayAlbumOrUser} – ` : ''}${file.size}

-
+ page.files = {} + + var prevPage = 0 + var nextPage = pageNum + 1 + + if (response.data.files.length < 25) { nextPage = pageNum } + + if (pageNum > 0) { prevPage = pageNum - 1 } + + var pagination = ` + ` - table.appendChild(div) - page.checkboxes = Array.from(table.getElementsByClassName('file-checkbox')) - page.lazyLoad.update() - } - } else { - let albumOrUser = 'Album' - if (page.username === 'root') { albumOrUser = 'User' } - - page.dom.innerHTML = ` - ${pagination} -
- ${controls} -
- - - - - - - - - - - - - -
File${albumOrUser}SizeDate
-
-
- ${pagination} - ` - - const table = document.getElementById('table') - - for (const file of response.data.files) { - const selected = page.selectedFiles.includes(file.id) - if (!selected && allFilesSelected) { allFilesSelected = false } - - page.files.set(file.id, { - name: file.name, - thumb: file.thumb - }) - - const tr = document.createElement('tr') - - let displayAlbumOrUser = file.album - if (page.username === 'root') { - displayAlbumOrUser = '' - if (file.username !== undefined) { displayAlbumOrUser = file.username } - } - - tr.innerHTML = ` - - - ${file.name} - ${displayAlbumOrUser} - ${file.size} - ${file.date} - - + var controls = ` +
+
+
+ +
+ ` + + var allFilesSelected = true + var table + var file + var selected + var displayAlbumOrUser + + if (page.filesView === 'thumbs') { + page.dom.innerHTML = ` + ${pagination} +
+ ${controls} +
+ +
+ ${pagination} + ` + + table = document.getElementById('table') + + for (file of response.data.files) { + selected = page.selectedFiles.includes(file.id) + if (!selected && allFilesSelected) { allFilesSelected = false } + + + displayAlbumOrUser = file.album + if (page.username === 'root') { + displayAlbumOrUser = '' + if (file.username !== undefined) { displayAlbumOrUser = file.username } + } + + var div = document.createElement('div') + div.className = 'image-container column is-narrow' + if (file.thumb !== undefined) { + div.innerHTML = `${file.name}` + } else { + div.innerHTML = `

${file.extname || 'N/A'}

` + } + div.innerHTML += ` + +
@@ -319,34 +244,123 @@ page.getUploads = async (album, pageNum, element) => { - - +
+
+

${file.name}

+

${displayAlbumOrUser ? `${displayAlbumOrUser} – ` : ''}${file.size}

+
+ ` + table.appendChild(div) + page.checkboxes = Array.from(table.getElementsByClassName('file-checkbox')) + page.lazyLoad.update() + } + } else { + var albumOrUser = 'Album' + if (page.username === 'root') { albumOrUser = 'User' } + + page.dom.innerHTML = ` + ${pagination} +
+ ${controls} +
+ + + + + + + + + + + + + +
File${albumOrUser}SizeDate
+
+
+ ${pagination} ` - table.appendChild(tr) - page.checkboxes = Array.from(table.getElementsByClassName('file-checkbox')) - } - } + table = document.getElementById('table') - if (allFilesSelected && response.data.files.length) { - const selectAll = document.getElementById('selectAll') - if (selectAll) { selectAll.checked = true } - } + for (file of response.data.files) { + selected = page.selectedFiles.includes(file.id) + if (!selected && allFilesSelected) { allFilesSelected = false } - page.currentView.album = album - page.currentView.pageNum = pageNum + page.files[file.id] = { + name: file.name, + thumb: file.thumb + } + + displayAlbumOrUser = file.album + if (page.username === 'root') { + displayAlbumOrUser = '' + if (file.username !== undefined) { displayAlbumOrUser = file.username } + } + + var tr = document.createElement('tr') + tr.innerHTML = ` + + + ${file.name} + ${displayAlbumOrUser} + ${file.size} + ${file.date} + + + + + + + + + + + + + + + + + + + + + + + + ` + + table.appendChild(tr) + page.checkboxes = Array.from(table.getElementsByClassName('file-checkbox')) + } + } + + if (allFilesSelected && response.data.files.length) { + var selectAll = document.getElementById('selectAll') + if (selectAll) { selectAll.checked = true } + } + + page.currentView.album = album + page.currentView.pageNum = pageNum + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) } -page.setFilesView = (view, element) => { +page.setFilesView = function (view, element) { localStorage.filesView = view page.filesView = view page.getUploads(page.currentView.album, page.currentView.pageNum, element) } -page.displayThumbnail = id => { - const file = page.files.get(id) +page.displayThumbnail = function (id) { + var file = page.files[id] if (!file.thumb) { return } - swal({ + return swal({ text: file.name, content: { element: 'img', @@ -356,16 +370,16 @@ page.displayThumbnail = id => { }) } -page.selectAllFiles = element => { - const table = document.getElementById('table') - const checkboxes = table.getElementsByClassName('file-checkbox') +page.selectAllFiles = function (element) { + var table = document.getElementById('table') + var checkboxes = table.getElementsByClassName('file-checkbox') - for (const checkbox of checkboxes) { - const id = parseInt(checkbox.dataset.id) + for (var i = 0; i < checkboxes.length; i++) { + var id = parseInt(checkboxes[i].dataset.id) if (isNaN(id)) { continue } - if (checkbox.checked !== element.checked) { - checkbox.checked = element.checked - if (checkbox.checked) { + if (checkboxes[i].checked !== element.checked) { + checkboxes[i].checked = element.checked + if (checkboxes[i].checked) { page.selectedFiles.push(id) } else { page.selectedFiles.splice(page.selectedFiles.indexOf(id), 1) @@ -382,18 +396,18 @@ page.selectAllFiles = element => { element.title = element.checked ? 'Unselect all files' : 'Select all files' } -page.selectInBetween = (element, lastElement) => { +page.selectInBetween = function (element, lastElement) { if (!element || !lastElement) { return } if (element === lastElement) { return } if (!page.checkboxes || !page.checkboxes.length) { return } - const thisIndex = page.checkboxes.indexOf(element) - const lastIndex = page.checkboxes.indexOf(lastElement) + var thisIndex = page.checkboxes.indexOf(element) + var lastIndex = page.checkboxes.indexOf(lastElement) - const distance = thisIndex - lastIndex + var distance = thisIndex - lastIndex if (distance >= -1 && distance <= 1) { return } - for (let i = 0; i < page.checkboxes.length; i++) { + for (var i = 0; i < page.checkboxes.length; i++) { if ((thisIndex > lastIndex && i > lastIndex && i < thisIndex) || (thisIndex < lastIndex && i > thisIndex && i < lastIndex)) { page.checkboxes[i].checked = true @@ -404,14 +418,14 @@ page.selectInBetween = (element, lastElement) => { localStorage.selectedFiles = JSON.stringify(page.selectedFiles) } -page.selectFile = (element, event) => { +page.selectFile = function (element, event) { if (event.shiftKey && page.lastSelected) { page.selectInBetween(element, page.lastSelected) } else { page.lastSelected = element } - const id = parseInt(element.dataset.id) + var id = parseInt(element.dataset.id) if (isNaN(id)) { return } @@ -428,41 +442,43 @@ page.selectFile = (element, event) => { } } -page.clearSelection = async () => { - const count = page.selectedFiles.length +page.clearSelection = function () { + var count = page.selectedFiles.length if (!count) { return swal('An error occurred!', 'You have not selected any files.', 'error') } - const suffix = `file${count === 1 ? '' : 's'}` - const proceed = await swal({ + var suffix = `file${count === 1 ? '' : 's'}` + return swal({ title: 'Are you sure?', text: `You are going to unselect ${count} ${suffix}.`, buttons: true }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const table = document.getElementById('table') - const checkboxes = table.getElementsByClassName('file-checkbox') + var table = document.getElementById('table') + var checkboxes = table.getElementsByClassName('file-checkbox') - for (const checkbox of checkboxes) { - if (checkbox.checked) { - checkbox.checked = false - } - } + for (var i = 0; i < checkboxes.length; i++) { + if (checkboxes[i].checked) { + checkboxes[i].checked = false + } + } - page.selectedFiles = [] - localStorage.removeItem('selectedFiles') + page.selectedFiles = [] + localStorage.removeItem('selectedFiles') - const selectAll = document.getElementById('selectAll') - if (selectAll) { selectAll.checked = false } + var selectAll = document.getElementById('selectAll') + if (selectAll) { selectAll.checked = false } - return swal('Cleared selection!', `Unselected ${count} ${suffix}.`, 'success') + return swal('Cleared selection!', `Unselected ${count} ${suffix}.`, 'success') + }) } -page.deleteFile = async id => { +page.deleteFile = function (id) { // TODO: Share function with bulk delete, just like 'add selected files to album' and 'add single file to album' - const proceed = await swal({ + swal({ title: 'Are you sure?', text: 'You won\'t be able to recover the file!', icon: 'warning', @@ -475,35 +491,39 @@ page.deleteFile = async id => { } } }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const response = await axios.post('api/upload/delete', { id }) - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.post('api/upload/delete', { id }) + .then(function (response) { + if (!response) { return } + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal('Deleted!', 'The file has been deleted.', 'success') + page.getUploads(page.currentView.album, page.currentView.pageNum) + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - swal('Deleted!', 'The file has been deleted.', 'success') - page.getUploads(page.currentView.album, page.currentView.pageNum) } -page.deleteSelectedFiles = async () => { - const count = page.selectedFiles.length +page.deleteSelectedFiles = function () { + var count = page.selectedFiles.length if (!count) { return swal('An error occurred!', 'You have not selected any files.', 'error') } - const suffix = `file${count === 1 ? '' : 's'}` - const proceed = await swal({ + var suffix = `file${count === 1 ? '' : 's'}` + swal({ title: 'Are you sure?', text: `You won't be able to recover ${count} ${suffix}!`, icon: 'warning', @@ -516,41 +536,47 @@ page.deleteSelectedFiles = async () => { } } }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const bulkdelete = await axios.post('api/upload/bulkdelete', { - field: 'id', - values: page.selectedFiles - }) - .catch(error => { - console.log(error) - swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.post('api/upload/bulkdelete', { + field: 'id', + values: page.selectedFiles + }) + .then(function (bulkdelete) { + if (!bulkdelete) { return } + + if (bulkdelete.data.success === false) { + if (bulkdelete.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', bulkdelete.data.description, 'error') + } + } + + var deleted = count + if (bulkdelete.data.failed && bulkdelete.data.failed.length) { + deleted -= bulkdelete.data.failed.length + page.selectedFiles = page.selectedFiles.filter(function (id) { + return bulkdelete.data.failed.includes(id) + }) + } else { + page.selectedFiles = [] + } + + localStorage.selectedFiles = JSON.stringify(page.selectedFiles) + + swal('Deleted!', `${deleted} file${deleted === 1 ? ' has' : 's have'} been deleted.`, 'success') + return page.getUploads(page.currentView.album, page.currentView.pageNum) + }) + .catch(function (error) { + console.log(error) + swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!bulkdelete) { return } - - if (bulkdelete.data.success === false) { - if (bulkdelete.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', bulkdelete.data.description, 'error') - } - } - - let deleted = count - if (bulkdelete.data.failed && bulkdelete.data.failed.length) { - deleted -= bulkdelete.data.failed.length - page.selectedFiles = page.selectedFiles.filter(id => bulkdelete.data.failed.includes(id)) - } else { - page.selectedFiles = [] - } - - localStorage.selectedFiles = JSON.stringify(page.selectedFiles) - - swal('Deleted!', `${deleted} file${deleted === 1 ? ' has' : 's have'} been deleted.`, 'success') - return page.getUploads(page.currentView.album, page.currentView.pageNum) } -page.deleteByNames = () => { +page.deleteByNames = function () { page.dom.innerHTML = `

Delete by names

@@ -575,15 +601,19 @@ page.deleteByNames = () => { ` } -page.deleteFileByNames = async () => { - const names = document.getElementById('names').value.split(/\r?\n/).filter(n => n.trim().length) - const count = names.length +page.deleteFileByNames = function () { + var names = document.getElementById('names').value + .split(/\r?\n/) + .filter(function (n) { + return n.trim().length + }) + var count = names.length if (!count) { return swal('An error occurred!', 'You have not entered any file names.', 'error') } - const suffix = `file${count === 1 ? '' : 's'}` - const proceed = await swal({ + var suffix = `file${count === 1 ? '' : 's'}` + swal({ title: 'Are you sure?', text: `You won't be able to recover ${count} ${suffix}!`, icon: 'warning', @@ -596,61 +626,69 @@ page.deleteFileByNames = async () => { } } }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const bulkdelete = await axios.post('api/upload/bulkdelete', { - field: 'name', - values: names - }) - .catch(error => { - console.log(error) - swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.post('api/upload/bulkdelete', { + field: 'name', + values: names + }) + .then(function (bulkdelete) { + if (!bulkdelete) { return } + + if (bulkdelete.data.success === false) { + if (bulkdelete.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', bulkdelete.data.description, 'error') + } + } + + var deleted = count + if (bulkdelete.data.failed && bulkdelete.data.failed.length) { + deleted -= bulkdelete.data.failed.length + } + + document.getElementById('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) + swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!bulkdelete) { return } - - if (bulkdelete.data.success === false) { - if (bulkdelete.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', bulkdelete.data.description, 'error') - } - } - - let deleted = count - if (bulkdelete.data.failed && bulkdelete.data.failed.length) { - deleted -= bulkdelete.data.failed.length - } - - document.getElementById('names').value = bulkdelete.data.failed.join('\n') - swal('Deleted!', `${deleted} file${deleted === 1 ? ' has' : 's have'} been deleted.`, 'success') } -page.addSelectedFilesToAlbum = async () => { - const count = page.selectedFiles.length +page.addSelectedFilesToAlbum = function () { + var count = page.selectedFiles.length if (!count) { return swal('An error occurred!', 'You have not selected any files.', 'error') } - const failed = await page.addFilesToAlbum(page.selectedFiles) - if (!failed) { return } - if (failed.length) { - page.selectedFiles = page.selectedFiles.filter(id => failed.includes(id)) - } else { - page.selectedFiles = [] - } - localStorage.selectedFiles = JSON.stringify(page.selectedFiles) - page.getUploads(page.currentView.album, page.currentView.pageNum) + page.addFilesToAlbum(page.selectedFiles, function (failed) { + if (!failed) { return } + if (failed.length) { + page.selectedFiles = page.selectedFiles.filter(function (id) { + return failed.includes(id) + }) + } else { + page.selectedFiles = [] + } + localStorage.selectedFiles = JSON.stringify(page.selectedFiles) + page.getUploads(page.currentView.album, page.currentView.pageNum) + }) } -page.addSingleFileToAlbum = async id => { - const failed = await page.addFilesToAlbum([id]) - if (!failed) { return } - page.getUploads(page.currentView.album, page.currentView.pageNum) +page.addSingleFileToAlbum = function (id) { + page.addFilesToAlbum([id], function (failed) { + if (!failed) { return } + page.getUploads(page.currentView.album, page.currentView.pageNum) + }) } -page.addFilesToAlbum = async ids => { - const count = ids.length - const proceed = await swal({ +page.addFilesToAlbum = function (ids, callback) { + var count = ids.length + return swal({ title: 'Are you sure?', text: `You are about to move ${count} file${count === 1 ? '' : 's'} to an album.`, buttons: { @@ -661,211 +699,221 @@ page.addFilesToAlbum = async ids => { } } }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const list = await axios.get('api/albums') - .catch(error => { - console.log(error) - swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.get('api/albums') + .then(function (list) { + if (!list) { return } + + if (list.data.success === false) { + if (list.data.description === 'No token provided') { + page.verifyToken(page.token) + } else { + swal('An error occurred!', list.data.description, 'error') + } + return + } + + if (!page.selectAlbumContainer) { + // We want to this to be re-usable + page.selectAlbumContainer = document.createElement('div') + page.selectAlbumContainer.id = 'selectAlbum' + } + + var options = list.data.albums + .map(function (album) { + return `` + }) + .join('\n') + + page.selectAlbumContainer.innerHTML = ` +
+ +
+
+ +
+
+ ` + + return swal({ + content: page.selectAlbumContainer, + buttons: { + cancel: true, + confirm: { + text: 'OK', + closeModal: false + } + } + }) + .then(function (choose) { + if (!choose) { return } + + var albumid = parseInt(page.selectAlbumContainer.getElementsByTagName('select')[0].value) + if (isNaN(albumid)) { + return swal('An error occurred!', 'You did not choose an album.', 'error') + } + + axios.post('api/albums/addfiles', { ids, albumid }) + .then(function (add) { + if (!add) { return } + + if (add.data.success === false) { + if (add.data.description === 'No token provided') { + page.verifyToken(page.token) + } else { + swal('An error occurred!', add.data.description, 'error') + } + return + } + + var added = ids.length + if (add.data.failed && add.data.failed.length) { + added -= add.data.failed.length + } + + var suffix = `file${ids.length === 1 ? '' : 's'}` + if (!added) { + return swal('An error occurred!', `Could not add the ${suffix} to the album.`, 'error') + } + + swal('Woohoo!', `Successfully ${albumid < 0 ? 'removed' : 'added'} ${added} ${suffix} ${albumid < 0 ? 'from' : 'to'} the album.`, 'success') + return callback(add.data.failed) + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) + }) + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!list) { return } - - if (list.data.success === false) { - if (list.data.description === 'No token provided') { - page.verifyToken(page.token) - } else { - swal('An error occurred!', list.data.description, 'error') - } - return - } - - if (!page.selectAlbumContainer) { - // We want to this to be re-usable - page.selectAlbumContainer = document.createElement('div') - page.selectAlbumContainer.id = 'selectAlbum' - } - - const options = list.data.albums - .map(album => ``) - .join('\n') - - page.selectAlbumContainer.innerHTML = ` -
- -
-
- -
-
- ` - - const choose = await swal({ - content: page.selectAlbumContainer, - buttons: { - cancel: true, - confirm: { - text: 'OK', - closeModal: false - } - } - }) - if (!choose) { return } - - const albumid = parseInt(page.selectAlbumContainer.getElementsByTagName('select')[0].value) - if (isNaN(albumid)) { - swal('An error occurred!', 'You did not choose an album.', 'error') - return - } - - const add = await axios.post('api/albums/addfiles', { ids, albumid }) - .catch(error => { - console.log(error) - swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') - }) - if (!add) { return } - - if (add.data.success === false) { - if (add.data.description === 'No token provided') { - page.verifyToken(page.token) - } else { - swal('An error occurred!', add.data.description, 'error') - } - return - } - - let added = ids.length - if (add.data.failed && add.data.failed.length) { - added -= add.data.failed.length - } - const suffix = `file${ids.length === 1 ? '' : 's'}` - - if (!added) { - swal('An error occurred!', `Could not add the ${suffix} to the album.`, 'error') - return - } - - swal('Woohoo!', `Successfully ${albumid < 0 ? 'removed' : 'added'} ${added} ${suffix} ${albumid < 0 ? 'from' : 'to'} the album.`, 'success') - return add.data.failed } -page.getAlbums = async () => { - const response = await axios.get('api/albums') - .catch(error => { +page.getAlbums = function () { + axios.get('api/albums') + .then(function (response) { + if (!response) { return } + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + page.albums = {} + + page.dom.innerHTML = ` +

Create new album

+ +
+
+ +
+
+ + + +
+ +

List of albums

+ +
+ + + + + + + + + + + + + +
IDNameFilesCreated atPublic link
+
+ ` + + var homeDomain = response.data.homeDomain + var table = document.getElementById('table') + + for (var album of response.data.albums) { + var albumUrl = `${homeDomain}/a/${album.identifier}` + + page.albums[album.id] = { + name: album.name, + download: album.download, + public: album.public + } + + var tr = document.createElement('tr') + tr.innerHTML = ` + + ${album.id} + ${album.name} + ${album.files} + ${album.date} + ${albumUrl} + + + + + + + + + + + + + + + + + + + + + + + + ` + + table.appendChild(tr) + } + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - page.albums.clear() - - page.dom.innerHTML = ` -

Create new album

- -
-
- -
-
- - - -
- -

List of albums

- -
- - - - - - - - - - - - - -
IDNameFilesCreated atPublic link
-
- ` - - const homeDomain = response.data.homeDomain - const table = document.getElementById('table') - - for (const album of response.data.albums) { - const albumUrl = `${homeDomain}/a/${album.identifier}` - - page.albums.set(album.id, { - name: album.name, - download: album.download, - public: album.public - }) - - const tr = document.createElement('tr') - tr.innerHTML = ` - - ${album.id} - ${album.name} - ${album.files} - ${album.date} - ${albumUrl} - - - - - - - - - - - - - - - - - - - - - - - - ` - - table.appendChild(tr) - } } -page.editAlbum = async id => { - const album = page.albums.get(id) +page.editAlbum = function (id) { + var album = page.albums[id] if (!album) { return } - const div = document.createElement('div') + var div = document.createElement('div') div.innerHTML = `
@@ -898,7 +946,7 @@ page.editAlbum = async id => {
` - const value = await swal({ + swal({ title: 'Edit album', icon: 'info', content: div, @@ -909,43 +957,47 @@ page.editAlbum = async id => { } } }) - if (!value) { return } + .then(function (value) { + if (!value) { return } - const response = await axios.post('api/albums/edit', { - id, - name: document.getElementById('_name').value, - download: document.getElementById('_download').checked, - public: document.getElementById('_public').checked, - requestLink: document.getElementById('_requestLink').checked - }) - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.post('api/albums/edit', { + id, + name: document.getElementById('_name').value, + download: document.getElementById('_download').checked, + public: document.getElementById('_public').checked, + requestLink: document.getElementById('_requestLink').checked + }) + .then(function (response) { + if (!response) { return } + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + if (response.data.identifier) { + swal('Success!', `Your album's new identifier is: ${response.data.identifier}.`, 'success') + } else if (response.data.name !== album.name) { + swal('Success!', `Your album was renamed to: ${response.data.name}.`, 'success') + } else { + swal('Success!', 'Your album was edited!', 'success') + } + + page.getAlbumsSidebar() + page.getAlbums() + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - if (response.data.identifier) { - swal('Success!', `Your album's new identifier is: ${response.data.identifier}.`, 'success') - } else if (response.data.name !== album.name) { - swal('Success!', `Your album was renamed to: ${response.data.name}.`, 'success') - } else { - swal('Success!', 'Your album was edited!', 'success') - } - - page.getAlbumsSidebar() - page.getAlbums() } -page.deleteAlbum = async id => { - const proceed = await swal({ +page.deleteAlbum = function (id) { + swal({ title: 'Are you sure?', text: 'This won\'t delete your files, only the album!', icon: 'warning', @@ -964,250 +1016,260 @@ page.deleteAlbum = async id => { } } }) - if (!proceed) { return } + .then(function (proceed) { + if (!proceed) { return } - const response = await axios.post('api/albums/delete', { - id, - purge: proceed === 'purge' - }) - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + axios.post('api/albums/delete', { + id, + purge: proceed === 'purge' + }) + .then(function (response) { + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal('Deleted!', 'Your album has been deleted.', 'success') + page.getAlbumsSidebar() + page.getAlbums() + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - swal('Deleted!', 'Your album has been deleted.', 'success') - page.getAlbumsSidebar() - page.getAlbums() } -page.submitAlbum = async element => { +page.submitAlbum = function (element) { page.isLoading(element, true) - const response = await axios.post('api/albums', { + axios.post('api/albums', { name: document.getElementById('albumName').value }) - .catch(error => { + .then(function (response) { + if (!response) { return } + + page.isLoading(element, false) + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal('Woohoo!', 'Album was created successfully', 'success') + page.getAlbumsSidebar() + page.getAlbums() + }) + .catch(function (error) { console.log(error) page.isLoading(element, false) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - page.isLoading(element, false) - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - swal('Woohoo!', 'Album was created successfully', 'success') - page.getAlbumsSidebar() - page.getAlbums() } -page.getAlbumsSidebar = async () => { - const response = await axios.get('api/albums/sidebar') - .catch(error => { +page.getAlbumsSidebar = function () { + axios.get('api/albums/sidebar') + .then(function (response) { + if (!response) { return } + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + var albumsContainer = document.getElementById('albumsContainer') + albumsContainer.innerHTML = '' + + if (response.data.albums === undefined) { return } + + for (var album of response.data.albums) { + var li = document.createElement('li') + var a = document.createElement('a') + a.id = album.id + a.innerHTML = album.name + + a.addEventListener('click', function () { + page.getAlbum(this) + }) + + li.appendChild(a) + albumsContainer.appendChild(li) + } + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - const albumsContainer = document.getElementById('albumsContainer') - albumsContainer.innerHTML = '' - - if (response.data.albums === undefined) { return } - - for (const album of response.data.albums) { - const li = document.createElement('li') - const a = document.createElement('a') - a.id = album.id - a.innerHTML = album.name - - a.addEventListener('click', function () { - page.getAlbum(this) - }) - - li.appendChild(a) - albumsContainer.appendChild(li) - } } -page.getAlbum = album => { +page.getAlbum = function (album) { page.setActiveMenu(album) page.getUploads(album.id) } -page.changeFileLength = async () => { - const response = await axios.get('api/filelength/config') - .catch(error => { +page.changeFileLength = function () { + axios.get('api/filelength/config') + .then(function (response) { + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + page.dom.innerHTML = ` +

File name length

+ +
+
+ +
+ +
+

Default file name length is ${response.data.config.default} characters. ${response.data.config.userChangeable ? `Range allowed for user is ${response.data.config.min} to ${response.data.config.max} characters.` : 'Changing file name length is disabled at the moment.'}

+
+ +
+ +
+
+ ` + + document.getElementById('setFileLength').addEventListener('click', function () { + page.setFileLength(document.getElementById('fileLength').value, this) + }) + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } +} - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } +page.setFileLength = function (fileLength, element) { + page.isLoading(element, true) - page.dom.innerHTML = ` -

File name length

+ axios.post('api/filelength/change', { fileLength }) + .then(function (response) { + page.isLoading(element, false) + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal({ + title: 'Woohoo!', + text: 'Your file length was successfully changed.', + icon: 'success' + }) + .then(function () { + page.changeFileLength() + }) + }) + .catch(function (error) { + console.log(error) + page.isLoading(element, false) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) +} + +page.changeToken = function () { + axios.get('api/tokens') + .then(function (response) { + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + page.dom.innerHTML = ` +

Manage your token

-
- -
- + +
+
+ +
-

Default file name length is ${response.data.config.default} characters. ${response.data.config.userChangeable ? `Range allowed for user is ${response.data.config.min} to ${response.data.config.max} characters.` : 'Changing file name length is disabled at the moment.'}

-
-
- ` - - document.getElementById('setFileLength').addEventListener('click', function () { - page.setFileLength(document.getElementById('fileLength').value, this) - }) +
+ ` + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) } -page.setFileLength = async (fileLength, element) => { +page.getNewToken = function (element) { page.isLoading(element, true) - const response = await axios.post('api/filelength/change', { fileLength }) - .catch(error => { + axios.post('api/tokens/change') + .then(function (response) { + page.isLoading(element, false) + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal({ + title: 'Woohoo!', + text: 'Your token was successfully changed.', + icon: 'success' + }) + .then(function () { + axios.defaults.headers.common.token = response.data.token + localStorage.token = response.data.token + page.token = response.data.token + page.changeToken() + }) + }) + .catch(function (error) { console.log(error) page.isLoading(element, false) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - page.isLoading(element, false) - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - await swal({ - title: 'Woohoo!', - text: 'Your file length was successfully changed.', - icon: 'success' - }) - - page.changeFileLength() } -page.changeToken = async () => { - const response = await axios.get('api/tokens') - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') - }) - if (!response) { return } - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - page.dom.innerHTML = ` -

Manage your token

- -
- -
-
- -
-
-
- - - ` -} - -page.getNewToken = async element => { - page.isLoading(element, true) - - const response = await axios.post('api/tokens/change') - .catch(error => { - console.log(error) - page.isLoading(element, false) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') - }) - if (!response) { return } - - page.isLoading(element, false) - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - await swal({ - title: 'Woohoo!', - text: 'Your token was successfully changed.', - icon: 'success' - }) - - axios.defaults.headers.common.token = response.data.token - localStorage.token = response.data.token - page.token = response.data.token - page.changeToken() -} - -page.changePassword = () => { +page.changePassword = function () { page.dom.innerHTML = `

Change your password

@@ -1250,51 +1312,55 @@ page.changePassword = () => { }) } -page.sendNewPassword = async (pass, element) => { +page.sendNewPassword = function (pass, element) { page.isLoading(element, true) - const response = await axios.post('api/password/change', { password: pass }) - .catch(error => { + axios.post('api/password/change', { password: pass }) + .then(function (response) { + page.isLoading(element, false) + + if (response.data.success === false) { + if (response.data.description === 'No token provided') { + return page.verifyToken(page.token) + } else { + return swal('An error occurred!', response.data.description, 'error') + } + } + + swal({ + title: 'Woohoo!', + text: 'Your password was successfully changed.', + icon: 'success' + }) + .then(function () { + page.changePassword() + }) + }) + .catch(function (error) { console.log(error) page.isLoading(element, false) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - page.isLoading(element, false) - - if (response.data.success === false) { - if (response.data.description === 'No token provided') { - return page.verifyToken(page.token) - } else { - return swal('An error occurred!', response.data.description, 'error') - } - } - - await swal({ - title: 'Woohoo!', - text: 'Your password was successfully changed.', - icon: 'success' - }) - - page.changePassword() } -page.setActiveMenu = activeItem => { - const menu = document.getElementById('menu') - const items = menu.getElementsByTagName('a') - for (const item of items) { item.classList.remove('is-active') } +page.setActiveMenu = function (activeItem) { + var menu = document.getElementById('menu') + var items = menu.getElementsByTagName('a') + for (var i = 0; i < items.length; i++) { + items[i].classList.remove('is-active') + } activeItem.classList.add('is-active') } -window.onload = () => { +window.onload = function () { // Add 'no-touch' class to non-touch devices if (!('ontouchstart' in document.documentElement)) { document.documentElement.classList.add('no-touch') } - const selectedFiles = localStorage.selectedFiles + var selectedFiles = localStorage.selectedFiles if (selectedFiles) { page.selectedFiles = JSON.parse(selectedFiles) } @@ -1303,11 +1369,11 @@ window.onload = () => { page.clipboardJS = new ClipboardJS('.clipboard-js') - page.clipboardJS.on('success', () => { + page.clipboardJS.on('success', function () { return swal('Copied!', 'The link has been copied to clipboard.', 'success') }) - page.clipboardJS.on('error', event => { + page.clipboardJS.on('error', function (event) { console.error(event) return swal('An error occurred!', 'There was an error when trying to copy the link to clipboard, please check the console for more information.', 'error') }) diff --git a/public/js/home.js b/public/js/home.js index 1e4d614..f16cd9d 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -1,6 +1,6 @@ /* global swal, axios, Dropzone, ClipboardJS, LazyLoad */ -const page = { +var page = { // user token token: localStorage.token, @@ -21,32 +21,32 @@ const page = { lazyLoad: null } -const imageExtensions = ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png'] +var imageExtensions = ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png'] -page.checkIfPublic = async () => { - const response = await axios.get('api/check') - .catch(error => { +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.chunkSize = response.data.chunkSize + page.preparePage() + }) + .catch(function (error) { console.log(error) - const button = document.getElementById('loginToUpload') + var button = document.getElementById('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') }) - if (!response) { return } - page.private = response.data.private - page.enableUserAccounts = response.data.enableUserAccounts - page.maxFileSize = response.data.maxFileSize - page.chunkSize = response.data.chunkSize - page.preparePage() } -page.preparePage = () => { +page.preparePage = function () { if (page.private) { if (page.token) { return page.verifyToken(page.token, true) } else { - const button = document.getElementById('loginToUpload') + var button = document.getElementById('loginToUpload') button.href = 'auth' button.classList.remove('is-loading') @@ -61,40 +61,40 @@ page.preparePage = () => { } } -page.verifyToken = async (token, reloadOnError) => { +page.verifyToken = function (token, reloadOnError) { if (reloadOnError === undefined) { reloadOnError = false } - const response = await axios.post('api/tokens/verify', { token }) - .catch(error => { + axios.post('api/tokens/verify', { token }) + .then(function (response) { + if (response.data.success === false) { + return swal({ + title: 'An error occurred!', + text: response.data.description, + icon: 'error' + }) + .then(function () { + if (!reloadOnError) { return } + localStorage.removeItem('token') + location.reload() + }) + } + + localStorage.token = token + page.token = token + return page.prepareUpload() + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - await swal({ - title: 'An error occurred!', - text: response.data.description, - icon: 'error' - }) - if (reloadOnError) { - localStorage.removeItem('token') - location.reload() - } - return - } - - localStorage.token = token - page.token = token - return page.prepareUpload() } -page.prepareUpload = () => { +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.addEventListener('change', () => { + page.albumSelect.addEventListener('change', function () { page.album = parseInt(page.albumSelect.value) }) @@ -111,18 +111,18 @@ page.prepareUpload = () => { document.getElementById('loginLinkText').innerHTML = 'Create an account and keep track of your uploads' } - const previewNode = document.querySelector('#tpl') + var previewNode = document.querySelector('#tpl') page.previewTemplate = previewNode.innerHTML previewNode.parentNode.removeChild(previewNode) page.prepareDropzone() - const tabs = document.getElementById('tabs') + var tabs = document.getElementById('tabs') if (tabs) { tabs.style.display = 'flex' - const items = tabs.getElementsByTagName('li') - for (const item of items) { - item.addEventListener('click', function () { + var items = tabs.getElementsByTagName('li') + for (var i = 0; i < items.length; i++) { + items[i].addEventListener('click', function () { page.setActiveTab(this.dataset.id) }) } @@ -135,57 +135,55 @@ page.prepareUpload = () => { } } -page.prepareAlbums = async () => { - const option = document.createElement('option') +page.prepareAlbums = function () { + var option = document.createElement('option') option.value = '' option.innerHTML = 'Upload to album' option.disabled = true option.selected = true page.albumSelect.appendChild(option) - const response = await axios.get('api/albums', { headers: { token: page.token } }) - .catch(error => { + axios.get('api/albums', { headers: { token: page.token } }) + .then(function (response) { + if (response.data.success === false) { + return swal('An error occurred!', response.data.description, 'error') + } + + // If the user doesn't have any albums we don't really need to display + // an album selection + if (!response.data.albums.length) { return } + + // Loop through the albums and create an option for each album + for (var album of response.data.albums) { + var option = document.createElement('option') + option.value = album.id + option.innerHTML = album.name + page.albumSelect.appendChild(option) + } + }) + .catch(function (error) { console.log(error) return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') }) - if (!response) { return } - - if (response.data.success === false) { - return swal('An error occurred!', response.data.description, 'error') - } - - const albums = response.data.albums - - // If the user doesn't have any albums we don't really need to display - // an album selection - if (albums.length === 0) { return } - - // Loop through the albums and create an option for each album - for (const album of albums) { - const option = document.createElement('option') - option.value = album.id - option.innerHTML = album.name - page.albumSelect.appendChild(option) - } } -page.setActiveTab = activeId => { - const items = document.getElementById('tabs').getElementsByTagName('li') - for (const item of items) { - const tabId = item.dataset.id +page.setActiveTab = function (activeId) { + var items = document.getElementById('tabs').getElementsByTagName('li') + for (var i = 0; i < items.length; i++) { + var tabId = items[i].dataset.id if (tabId === activeId) { - item.classList.add('is-active') + items[i].classList.add('is-active') document.getElementById(tabId).style.display = 'block' } else { - item.classList.remove('is-active') + items[i].classList.remove('is-active') document.getElementById(tabId).style.display = 'none' } } } -page.prepareDropzone = () => { - const tabDiv = document.getElementById('tab-files') - const div = document.createElement('div') +page.prepareDropzone = function () { + var tabDiv = document.getElementById('tab-files') + var div = document.createElement('div') div.className = 'control is-expanded' div.innerHTML = `
@@ -197,7 +195,7 @@ page.prepareDropzone = () => { ` tabDiv.getElementsByClassName('dz-container')[0].appendChild(div) - const previewsContainer = tabDiv.getElementsByClassName('uploads')[0] + var previewsContainer = tabDiv.getElementsByClassName('uploads')[0] page.dropzone = new Dropzone('#dropzone', { url: 'api/upload', paramName: 'files[]', @@ -213,12 +211,12 @@ page.prepareDropzone = () => { 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 - chunksUploaded: async (file, done) => { + chunksUploaded: function (file, done) { file.previewElement.querySelector('.progress').setAttribute('value', 100) file.previewElement.querySelector('.progress').innerHTML = '100%' // The API supports an array of multiple files - const response = await axios.post('api/upload/finishchunks', + return axios.post('api/upload/finishchunks', { files: [{ uuid: file.upload.uuid, @@ -229,47 +227,51 @@ page.prepareDropzone = () => { albumid: page.album }] }, - { headers: { token: page.token } }) - .then(response => response.data) - .catch(error => { + { + headers: { + token: page.token + } + }) + .then(function (response) { + file.previewElement.querySelector('.progress').style.display = 'none' + + if (response.data.success === false) { + file.previewElement.querySelector('.error').innerHTML = response.data.description + } + + if (response.data.files && response.data.files[0]) { + page.updateTemplate(file, response.data.files[0]) + } + return done() + }) + .catch(function (error) { return { success: false, description: error.toString() } }) - - file.previewElement.querySelector('.progress').style.display = 'none' - - if (response.success === false) { - file.previewElement.querySelector('.error').innerHTML = response.description - } - - if (response.files && response.files[0]) { - page.updateTemplate(file, response.files[0]) - } - return done() } }) - page.dropzone.on('addedfile', file => { + page.dropzone.on('addedfile', function (file) { tabDiv.getElementsByClassName('uploads')[0].style.display = 'block' file.previewElement.querySelector('.name').innerHTML = file.name }) // Add the selected albumid, if an album is selected, as a header - page.dropzone.on('sending', (file, xhr, formData) => { + page.dropzone.on('sending', function (file, xhr) { if (file.upload.chunked) { return } if (page.album) { xhr.setRequestHeader('albumid', page.album) } }) // Update the total progress bar - page.dropzone.on('uploadprogress', (file, progress, bytesSent) => { + page.dropzone.on('uploadprogress', function (file, progress) { if (file.upload.chunked && progress === 100) { return } file.previewElement.querySelector('.progress').setAttribute('value', progress) file.previewElement.querySelector('.progress').innerHTML = `${progress}%` }) - page.dropzone.on('success', (file, response) => { + page.dropzone.on('success', function (file, response) { if (!response) { return } file.previewElement.querySelector('.progress').style.display = 'none' // file.previewElement.querySelector('.name').innerHTML = file.name @@ -283,7 +285,7 @@ page.prepareDropzone = () => { } }) - page.dropzone.on('error', (file, error) => { + page.dropzone.on('error', function (file, error) { file.previewElement.querySelector('.progress').style.display = 'none' file.previewElement.querySelector('.name').innerHTML = file.name file.previewElement.querySelector('.error').innerHTML = error @@ -292,43 +294,57 @@ page.prepareDropzone = () => { page.prepareShareX() } -page.uploadUrls = async button => { - const tabDiv = document.getElementById('tab-urls') +page.uploadUrls = function (button) { + var tabDiv = document.getElementById('tab-urls') if (!tabDiv) { return } if (button.classList.contains('is-loading')) { return } button.classList.add('is-loading') - await new Promise(async (resolve, reject) => { - const albumid = page.album - const previewsContainer = tabDiv.getElementsByClassName('uploads')[0] - const urls = document.getElementById('urls').value + function done(error) { + if (error) { swal('An error occurred!', error, 'error') } + button.classList.remove('is-loading') + } + + function run() { + var albumid = page.album + var previewsContainer = tabDiv.getElementsByClassName('uploads')[0] + var urls = document.getElementById('urls').value .split(/\r?\n/) - .filter(url => url.trim().length) + .filter(function (url) { return url.trim().length }) document.getElementById('urls').value = urls.join('\n') if (!urls.length) { // eslint-disable-next-line prefer-promise-reject-errors - return reject('You have not entered any URLs.') + return done('You have not entered any URLs.') } tabDiv.getElementsByClassName('uploads')[0].style.display = 'block' - const files = urls.map(url => { - const previewTemplate = document.createElement('template') + var files = urls.map(function (url) { + var previewTemplate = document.createElement('template') previewTemplate.innerHTML = page.previewTemplate.trim() - const previewElement = previewTemplate.content.firstChild + var previewElement = previewTemplate.content.firstChild previewElement.querySelector('.name').innerHTML = url previewsContainer.appendChild(previewElement) - return { - url, - previewElement - } + return { url, previewElement } }) - const post = async i => { - if (i === files.length) { return resolve() } - const file = files[i] - const response = await axios.post('api/upload', + function post(i) { + if (i === files.length) { return done() } + + var file = files[i] + + function posted(result) { + file.previewElement.querySelector('.progress').style.display = 'none' + if (result.success) { + page.updateTemplate(file, result.files[0]) + } else { + file.previewElement.querySelector('.error').innerHTML = result.description + } + return post(i + 1) + } + + axios.post('api/upload', { urls: [file.url] }, @@ -338,41 +354,32 @@ page.uploadUrls = async button => { albumid } }) - .then(response => response.data) - .catch(error => { - return { + .then(function (response) { + return posted(response.data) + }) + .catch(function (error) { + return posted({ success: false, description: error.toString() - } + }) }) - - file.previewElement.querySelector('.progress').style.display = 'none' - if (response.success) { - page.updateTemplate(file, response.files[0]) - } else { - file.previewElement.querySelector('.error').innerHTML = response.description - } - post(i + 1) } - post(0) - }).catch(error => { - swal('An error occurred!', error.toString(), 'error') - }) - - button.classList.remove('is-loading') + return post(0) + } + return run() } -page.updateTemplate = (file, response) => { +page.updateTemplate = function (file, response) { if (!response.url) { return } - const a = file.previewElement.querySelector('.link > a') - const clipboard = file.previewElement.querySelector('.clipboard-mobile > .clipboard-js') + var a = file.previewElement.querySelector('.link > a') + var clipboard = file.previewElement.querySelector('.clipboard-mobile > .clipboard-js') a.href = a.innerHTML = clipboard.dataset['clipboardText'] = response.url clipboard.parentElement.style.display = 'block' - const exec = /.[\w]+(\?|$)/.exec(response.url) + var exec = /.[\w]+(\?|$)/.exec(response.url) if (exec && exec[0] && imageExtensions.includes(exec[0].toLowerCase())) { - const img = file.previewElement.querySelector('img') + var img = file.previewElement.querySelector('img') img.setAttribute('alt', response.name || '') img.dataset['src'] = response.url img.onerror = function () { this.style.display = 'none' } // hide webp in firefox and ie @@ -380,10 +387,10 @@ page.updateTemplate = (file, response) => { } } -page.prepareShareX = () => { +page.prepareShareX = function () { if (page.token) { - const sharexElement = document.getElementById('ShareX') - const sharexFile = + var sharexElement = document.getElementById('ShareX') + var sharexFile = '{\r\n' + ` "Name": "${location.hostname}",\r\n` + ' "DestinationType": "ImageUploader, FileUploader",\r\n' + @@ -397,14 +404,14 @@ page.prepareShareX = () => { ' "URL": "$json:files[0].url$",\r\n' + ' "ThumbnailURL": "$json:files[0].url$"\r\n' + '}' - const sharexBlob = new Blob([sharexFile], { type: 'application/octet-binary' }) + var sharexBlob = new Blob([sharexFile], { type: 'application/octet-binary' }) sharexElement.setAttribute('href', URL.createObjectURL(sharexBlob)) sharexElement.setAttribute('download', `${location.hostname}.sxcu`) } } -page.createAlbum = async () => { - const div = document.createElement('div') +page.createAlbum = function () { + var div = document.createElement('div') div.innerHTML = `
@@ -429,7 +436,7 @@ page.createAlbum = async () => {
` - const value = await swal({ + swal({ title: 'Create new album', icon: 'info', content: div, @@ -440,61 +447,66 @@ page.createAlbum = async () => { } } }) - if (!value) { return } + .then(function (value) { + if (!value) { return } - const name = document.getElementById('_name').value - const response = await axios.post('api/albums', { - name, - download: document.getElementById('_download').checked, - public: document.getElementById('_public').checked - }, { headers: { token: page.token } }) - .catch(error => { - console.log(error) - return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + var name = document.getElementById('_name').value + axios.post('api/albums', { + name, + download: document.getElementById('_download').checked, + public: document.getElementById('_public').checked + }, { headers: { token: page.token } }) + .then(function (response) { + if (response.data.success === false) { + return swal('An error occurred!', response.data.description, 'error') + } + + var option = document.createElement('option') + option.value = response.data.id + option.innerHTML = name + page.albumSelect.appendChild(option) + + swal('Woohoo!', 'Album was created successfully', 'success') + }) + .catch(function (error) { + console.log(error) + return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error') + }) }) - if (!response) { return } - if (response.data.success === false) { - return swal('An error occurred!', response.data.description, 'error') - } - - const option = document.createElement('option') - option.value = response.data.id - option.innerHTML = name - page.albumSelect.appendChild(option) - - swal('Woohoo!', 'Album was created successfully', 'success') } // Handle image paste event -window.addEventListener('paste', event => { - const items = (event.clipboardData || event.originalEvent.clipboardData).items - for (const index in items) { - const item = items[index] +window.addEventListener('paste', function (event) { + var items = (event.clipboardData || event.originalEvent.clipboardData).items + for (var index in items) { + var item = items[index] if (item.kind === 'file') { - const blob = item.getAsFile() - console.log(blob.type) - const file = new File([blob], `pasted-image.${blob.type.match(/(?:[^/]*\/)([^;]*)/)[1]}`) + var blob = item.getAsFile() + var file = new File([blob], `pasted-image.${blob.type.match(/(?:[^/]*\/)([^;]*)/)[1]}`) file.type = blob.type - console.log(file) page.dropzone.addFile(file) } } }) -window.onload = () => { +window.onload = function () { page.checkIfPublic() page.clipboardJS = new ClipboardJS('.clipboard-js') - page.clipboardJS.on('success', () => { + page.clipboardJS.on('success', function () { return swal('Copied!', 'The link has been copied to clipboard.', 'success') }) - page.clipboardJS.on('error', event => { + page.clipboardJS.on('error', function (event) { console.error(event) return swal('An error occurred!', 'There was an error when trying to copy the link to clipboard, please check the console for more information.', 'error') }) page.lazyLoad = new LazyLoad() + + document.getElementById('createAlbum').addEventListener('click', function () { + page.createAlbum() + }) } diff --git a/scripts/thumbs.js b/scripts/thumbs.js index 2f6ce17..569e490 100644 --- a/scripts/thumbs.js +++ b/scripts/thumbs.js @@ -38,9 +38,9 @@ thumbs.do = async () => { thumbs.force = parseInt(args[1]) if ((isNaN(thumbs.mode) || ![1, 2, 3].includes(thumbs.mode)) || (!isNaN(thumbs.force) && ![0, 1].includes(thumbs.force))) { - console.log('Usage : node THIS_FILE [force=0|1]') - console.log('mode : 1 = images only, 2 = videos only, 3 = both images and videos') - console.log('force : 0 = no force (default), 1 = overwrite existing thumbnails') + console.log('Usage:\nyarn thumbs [force=0|1]\n') + console.log('mode : 1 = images only, 2 = videos only, 3 = both images and videos') + console.log('force: 0 = no force (default), 1 = overwrite existing thumbnails') return } diff --git a/views/_globals.njk b/views/_globals.njk index 8868d91..3fb9cf9 100644 --- a/views/_globals.njk +++ b/views/_globals.njk @@ -13,7 +13,7 @@ v2: Images and config files (manifest.json, browserconfig.xml, etc). v3: CSS and JS files (libs such as bulma, lazyload, etc). #} -{% set v1 = "BvoZYURztW" %} +{% set v1 = "iz81GIx05U" %} {% set v2 = "Ii3JYKIhb0" %} {% set v3 = "HrvcYD3KTh" %} diff --git a/views/album.njk b/views/album.njk index a97451a..37aae49 100644 --- a/views/album.njk +++ b/views/album.njk @@ -8,6 +8,7 @@ {% endblock %} {% block scripts %} + {% endblock %} diff --git a/views/auth.njk b/views/auth.njk index 89b8135..1dd1e00 100644 --- a/views/auth.njk +++ b/views/auth.njk @@ -28,34 +28,36 @@

Login or register

-
-
- +
+
+
+ +
-
-
-
- +
+
+ +
-
-
-
- - - - - Register - +
+ +
+ +
- -
+
diff --git a/views/dashboard.njk b/views/dashboard.njk index 522c873..c6ae863 100644 --- a/views/dashboard.njk +++ b/views/dashboard.njk @@ -53,16 +53,16 @@ Frontpage
  • - Uploads + Uploads
  • - Delete by names + Delete by names