mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-31 07:11:33 +00:00
Updates (WARNING!)
WARNING: Please turn off lolisafe before upgrading, then run "node database/migration.js" once after upgrading. Ignore all errors/warnings about duplicate column name. Afterwards make sure your config.js follows the new format in config.sample.js (specifically fileLength and generateThumbnails options). * generateImageThumbnails and generateVideoThumbnails options in config.js is now renamed to an object named generateThumbnails, with image and video as its properties. * fileLength option is now an object with min, max, default and userChangeable as its properties. * User may now change their preferred file length (following the previous option, of course). * Updated a bunch of responses messages. Mainly appending a dot to the messages. * New APIs: /fileLength/config to get an object of the current fileLength config (exactly what is in the config.js file). /fileLength/change to change user's preferred file length. * And maybe some others ...?
This commit is contained in:
parent
763d06ff95
commit
616124446f
@ -64,8 +64,21 @@ module.exports = {
|
||||
*/
|
||||
maxSize: '512MB',
|
||||
|
||||
// The length of the random generated name for the uploaded files
|
||||
fileLength: 32,
|
||||
/*
|
||||
The length of the random generated name for the uploaded files.
|
||||
If "userChangeable" is set to true, registered users will be able to change
|
||||
their preferred file name length from the dashboard. The allowed range will
|
||||
be set by "min" and "max". Otherwise it will use "default".
|
||||
Technically it's possible to have "default" outside of the "min" and "max" range,
|
||||
but please not. Once a user has changed to a number within the range, the user will
|
||||
no longer be able to use the default value.
|
||||
*/
|
||||
fileLength: {
|
||||
min: 4,
|
||||
max: 32,
|
||||
default: 32,
|
||||
userChangeable: false
|
||||
},
|
||||
|
||||
/*
|
||||
This option will limit how many times it will try to generate random names
|
||||
@ -79,8 +92,10 @@ module.exports = {
|
||||
to install a separate binary called graphicsmagick (http://www.graphicsmagick.org)
|
||||
for images and ffmpeg (https://ffmpeg.org/) for video files
|
||||
*/
|
||||
generateImageThumbnails: true,
|
||||
generateVideoThumbnails: false,
|
||||
generateThumbnails: {
|
||||
image: true,
|
||||
video: false
|
||||
},
|
||||
|
||||
/*
|
||||
Allows users to download a .zip file of all files in an album.
|
||||
|
@ -46,7 +46,7 @@ albumsController.create = async (req, res, next) => {
|
||||
|
||||
const name = req.body.name
|
||||
if (name === undefined || name === '') {
|
||||
return res.json({ success: false, description: 'No album name specified' })
|
||||
return res.json({ success: false, description: 'No album name specified.' })
|
||||
}
|
||||
|
||||
const album = await db.table('albums').where({
|
||||
@ -56,7 +56,7 @@ albumsController.create = async (req, res, next) => {
|
||||
}).first()
|
||||
|
||||
if (album) {
|
||||
return res.json({ success: false, description: 'There\'s already an album with that name' })
|
||||
return res.json({ success: false, description: 'There\'s already an album with that name.' })
|
||||
}
|
||||
|
||||
await db.table('albums').insert({
|
||||
@ -77,7 +77,7 @@ albumsController.delete = async (req, res, next) => {
|
||||
|
||||
const id = req.body.id
|
||||
if (id === undefined || id === '') {
|
||||
return res.json({ success: false, description: 'No album specified' })
|
||||
return res.json({ success: false, description: 'No album specified.' })
|
||||
}
|
||||
|
||||
await db.table('albums').where({ id: id, userid: user.id }).update({ enabled: 0 })
|
||||
@ -89,17 +89,17 @@ albumsController.rename = async (req, res, next) => {
|
||||
|
||||
const id = req.body.id
|
||||
if (id === undefined || id === '') {
|
||||
return res.json({ success: false, description: 'No album specified' })
|
||||
return res.json({ success: false, description: 'No album specified.' })
|
||||
}
|
||||
|
||||
const name = req.body.name
|
||||
if (name === undefined || name === '') {
|
||||
return res.json({ success: false, description: 'No name specified' })
|
||||
return res.json({ success: false, description: 'No name specified.' })
|
||||
}
|
||||
|
||||
const album = await db.table('albums').where({ name: name, userid: user.id }).first()
|
||||
if (album) {
|
||||
return res.json({ success: false, description: 'Name already in use' })
|
||||
return res.json({ success: false, description: 'Name already in use.' })
|
||||
}
|
||||
|
||||
await db.table('albums').where({ id: id, userid: user.id }).update({ name: name })
|
||||
@ -108,10 +108,10 @@ albumsController.rename = async (req, res, next) => {
|
||||
|
||||
albumsController.get = async (req, res, next) => {
|
||||
const identifier = req.params.identifier
|
||||
if (identifier === undefined) return res.status(401).json({ success: false, description: 'No identifier provided' })
|
||||
if (identifier === undefined) return res.status(401).json({ success: false, description: 'No identifier provided.' })
|
||||
|
||||
const album = await db.table('albums').where({ identifier, enabled: 1 }).first()
|
||||
if (!album) return res.json({ success: false, description: 'Album not found' })
|
||||
if (!album) return res.json({ success: false, description: 'Album not found.' })
|
||||
|
||||
const title = album.name
|
||||
const files = await db.table('files').select('name').where('albumid', album.id).orderBy('id', 'DESC')
|
||||
@ -120,7 +120,7 @@ albumsController.get = async (req, res, next) => {
|
||||
file.file = `${config.domain}/${file.name}`
|
||||
|
||||
const ext = path.extname(file.name).toLowerCase()
|
||||
if ((config.uploads.generateImageThumbnails && utils.imageExtensions.includes(ext)) || (config.uploads.generateVideoThumbnails && utils.videoExtensions.includes(ext))) {
|
||||
if ((config.uploads.generateThumbnails.image && utils.imageExtensions.includes(ext)) || (config.uploads.generateThumbnails.video && utils.videoExtensions.includes(ext))) {
|
||||
file.thumb = `${config.domain}/thumbs/${file.name.slice(0, -ext.length)}.png`
|
||||
}
|
||||
}
|
||||
@ -135,11 +135,11 @@ albumsController.get = async (req, res, next) => {
|
||||
|
||||
albumsController.generateZip = async (req, res, next) => {
|
||||
const identifier = req.params.identifier
|
||||
if (identifier === undefined) return res.status(401).json({ success: false, description: 'No identifier provided' })
|
||||
if (!config.uploads.generateZips) return res.status(401).json({ success: false, description: 'Zip generation disabled' })
|
||||
if (identifier === undefined) return res.status(401).json({ success: false, description: 'No identifier provided.' })
|
||||
if (!config.uploads.generateZips) return res.status(401).json({ success: false, description: 'Zip generation disabled.' })
|
||||
|
||||
const album = await db.table('albums').where({ identifier, enabled: 1 }).first()
|
||||
if (!album) return res.json({ success: false, description: 'Album not found' })
|
||||
if (!album) return res.json({ success: false, description: 'Album not found.' })
|
||||
|
||||
if (album.zipGeneratedAt > album.editedAt) {
|
||||
const filePath = path.join(config.uploads.folder, 'zips', `${identifier}.zip`)
|
||||
@ -148,7 +148,7 @@ albumsController.generateZip = async (req, res, next) => {
|
||||
} else {
|
||||
console.log(`Generating zip for album identifier: ${identifier}`)
|
||||
const files = await db.table('files').select('name').where('albumid', album.id)
|
||||
if (files.length === 0) return res.json({ success: false, description: 'There are no files in the album' })
|
||||
if (files.length === 0) return res.json({ success: false, description: 'There are no files in the album.' })
|
||||
|
||||
const zipPath = path.join(__dirname, '..', config.uploads.folder, 'zips', `${album.identifier}.zip`)
|
||||
let archive = new Zip()
|
||||
|
@ -10,53 +10,53 @@ authController.verify = async (req, res, next) => {
|
||||
const username = req.body.username
|
||||
const password = req.body.password
|
||||
|
||||
if (username === undefined) return res.json({ success: false, description: 'No username provided' })
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided' })
|
||||
if (username === undefined) return res.json({ success: false, description: 'No username provided.' })
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided.' })
|
||||
|
||||
const user = await db.table('users').where('username', username).first()
|
||||
if (!user) return res.json({ success: false, description: 'Username doesn\'t exist' })
|
||||
if (!user) return res.json({ success: false, description: 'Username doesn\'t exist.' })
|
||||
if (user.enabled === false || user.enabled === 0) {
|
||||
return res.json({
|
||||
success: false,
|
||||
description: 'This account has been disabled'
|
||||
description: 'This account has been disabled.'
|
||||
})
|
||||
}
|
||||
|
||||
bcrypt.compare(password, user.password, (err, result) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return res.json({ success: false, description: 'There was an error' })
|
||||
return res.json({ success: false, description: 'There was an error.' })
|
||||
}
|
||||
if (result === false) return res.json({ success: false, description: 'Wrong password' })
|
||||
if (result === false) return res.json({ success: false, description: 'Wrong password.' })
|
||||
return res.json({ success: true, token: user.token })
|
||||
})
|
||||
}
|
||||
|
||||
authController.register = async (req, res, next) => {
|
||||
if (config.enableUserAccounts === false) {
|
||||
return res.json({ success: false, description: 'Register is disabled at the moment' })
|
||||
return res.json({ success: false, description: 'Register is disabled at the moment.' })
|
||||
}
|
||||
|
||||
const username = req.body.username
|
||||
const password = req.body.password
|
||||
|
||||
if (username === undefined) return res.json({ success: false, description: 'No username provided' })
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided' })
|
||||
if (username === undefined) return res.json({ success: false, description: 'No username provided.' })
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided.' })
|
||||
|
||||
if (username.length < 4 || username.length > 32) {
|
||||
return res.json({ success: false, description: 'Username must have 4-32 characters' })
|
||||
return res.json({ success: false, description: 'Username must have 4-32 characters.' })
|
||||
}
|
||||
if (password.length < 6 || password.length > 64) {
|
||||
return res.json({ success: false, description: 'Password must have 6-64 characters' })
|
||||
return res.json({ success: false, description: 'Password must have 6-64 characters.' })
|
||||
}
|
||||
|
||||
const user = await db.table('users').where('username', username).first()
|
||||
if (user) return res.json({ success: false, description: 'Username already exists' })
|
||||
if (user) return res.json({ success: false, description: 'Username already exists.' })
|
||||
|
||||
bcrypt.hash(password, 10, async (err, hash) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return res.json({ success: false, description: 'Error generating password hash (╯°□°)╯︵ ┻━┻' })
|
||||
return res.json({ success: false, description: 'Error generating password hash (╯°□°)╯︵ ┻━┻.' })
|
||||
}
|
||||
const token = randomstring.generate(64)
|
||||
await db.table('users').insert({
|
||||
@ -73,16 +73,16 @@ authController.changePassword = async (req, res, next) => {
|
||||
const user = await utils.authorize(req, res)
|
||||
|
||||
let password = req.body.password
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided' })
|
||||
if (password === undefined) return res.json({ success: false, description: 'No password provided.' })
|
||||
|
||||
if (password.length < 6 || password.length > 64) {
|
||||
return res.json({ success: false, description: 'Password must have 6-64 characters' })
|
||||
return res.json({ success: false, description: 'Password must have 6-64 characters.' })
|
||||
}
|
||||
|
||||
bcrypt.hash(password, 10, async (err, hash) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return res.json({ success: false, description: 'Error generating password hash (╯°□°)╯︵ ┻━┻' })
|
||||
return res.json({ success: false, description: 'Error generating password hash (╯°□°)╯︵ ┻━┻.' })
|
||||
}
|
||||
|
||||
await db.table('users').where('id', user.id).update({ password: hash })
|
||||
@ -90,4 +90,32 @@ authController.changePassword = async (req, res, next) => {
|
||||
})
|
||||
}
|
||||
|
||||
authController.getFileLengthConfig = async (req, res, next) => {
|
||||
const user = await utils.authorize(req, res)
|
||||
return res.json({ success: true, fileLength: user.fileLength, config: config.uploads.fileLength })
|
||||
}
|
||||
|
||||
authController.changeFileLength = async (req, res, next) => {
|
||||
if (config.uploads.fileLength.userChangeable === false) {
|
||||
return res.json({ success: false, description: 'Changing file length is disabled at the moment.' })
|
||||
}
|
||||
|
||||
const user = await utils.authorize(req, res)
|
||||
|
||||
let fileLength = parseInt(req.body.fileLength)
|
||||
if (fileLength === undefined) return res.json({ success: false, description: 'No file length provided.' })
|
||||
if (isNaN(fileLength)) return res.json({ success: false, description: 'File length is not a valid number.' })
|
||||
|
||||
if (fileLength < config.uploads.fileLength.min || fileLength > config.uploads.fileLength.max) {
|
||||
return res.json({ success: false, description: `File length must be ${config.uploads.fileLength.min} to ${config.uploads.fileLength.max} characters` })
|
||||
}
|
||||
|
||||
if (fileLength === user.fileLength) {
|
||||
return res.json({ success: true })
|
||||
}
|
||||
|
||||
await db.table('users').where('id', user.id).update({ fileLength })
|
||||
return res.json({ success: true })
|
||||
}
|
||||
|
||||
module.exports = authController
|
||||
|
@ -7,10 +7,10 @@ const tokenController = {}
|
||||
|
||||
tokenController.verify = async (req, res, next) => {
|
||||
const token = req.body.token
|
||||
if (token === undefined) return res.status(401).json({ success: false, description: 'No token provided' })
|
||||
if (token === undefined) return res.status(401).json({ success: false, description: 'No token provided.' })
|
||||
|
||||
const user = await db.table('users').where('token', token).first()
|
||||
if (!user) return res.status(401).json({ success: false, description: 'Invalid token' })
|
||||
if (!user) return res.status(401).json({ success: false, description: 'Invalid token.' })
|
||||
return res.json({ success: true, username: user.username })
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,10 @@ const storage = multer.diskStorage({
|
||||
cb(null, uploadDir)
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
// If the user has a preferred file length, make sure it follows the allowed range
|
||||
const fileLength = req.params.fileLength ? Math.min(Math.max(req.params.fileLength, config.uploads.fileLength.min), config.uploads.fileLength.max) : config.uploads.fileLength.default
|
||||
const access = i => {
|
||||
const name = randomstring.generate(config.uploads.fileLength) + path.extname(file.originalname)
|
||||
const name = randomstring.generate(fileLength) + path.extname(file.originalname)
|
||||
fs.access(path.join(uploadDir, name), err => {
|
||||
if (err) return cb(null, name)
|
||||
console.log(`A file named "${name}" already exists (${++i}/${maxTries}).`)
|
||||
@ -36,12 +38,10 @@ const upload = multer({
|
||||
storage: storage,
|
||||
limits: { fileSize: config.uploads.maxSize },
|
||||
fileFilter: function (req, file, cb) {
|
||||
if (config.blockedExtensions !== undefined) {
|
||||
if (config.blockedExtensions.some(extension => path.extname(file.originalname).toLowerCase() === extension)) {
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
return cb('This file extension is not allowed')
|
||||
}
|
||||
return cb(null, true)
|
||||
if (config.blockedExtensions === undefined) return cb(null, true)
|
||||
if (config.blockedExtensions.some(extension => path.extname(file.originalname).toLowerCase() === extension)) {
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
return cb('This file extension is not allowed.')
|
||||
}
|
||||
return cb(null, true)
|
||||
}
|
||||
@ -57,9 +57,12 @@ uploadsController.upload = async (req, res, next) => {
|
||||
if (user && (user.enabled === false || user.enabled === 0)) {
|
||||
return res.json({
|
||||
success: false,
|
||||
description: 'This account has been disabled'
|
||||
description: 'This account has been disabled.'
|
||||
})
|
||||
}
|
||||
if (user && user.fileLength) {
|
||||
req.params.fileLength = user.fileLength
|
||||
}
|
||||
const albumid = req.headers.albumid || req.params.albumid
|
||||
|
||||
if (albumid && user) {
|
||||
@ -67,7 +70,7 @@ uploadsController.upload = async (req, res, next) => {
|
||||
if (!album) {
|
||||
return res.json({
|
||||
success: false,
|
||||
description: 'Album doesn\'t exist or it doesn\'t belong to the user'
|
||||
description: 'Album doesn\'t exist or it doesn\'t belong to the user.'
|
||||
})
|
||||
}
|
||||
return uploadsController.actuallyUpload(req, res, user, albumid)
|
||||
@ -167,14 +170,14 @@ uploadsController.processFilesForDisplay = async (req, res, files, existingFiles
|
||||
|
||||
for (let file of files) {
|
||||
let ext = path.extname(file.name).toLowerCase()
|
||||
if ((config.uploads.generateImageThumbnails && utils.imageExtensions.includes(ext)) || (config.uploads.generateVideoThumbnails && utils.videoExtensions.includes(ext))) {
|
||||
if ((config.uploads.generateThumbnails.image && utils.imageExtensions.includes(ext)) || (config.uploads.generateThumbnails.video && utils.videoExtensions.includes(ext))) {
|
||||
file.thumb = `${basedomain}/thumbs/${file.name.slice(0, -ext.length)}.png`
|
||||
utils.generateThumbs(file)
|
||||
}
|
||||
|
||||
if (file.albumid) {
|
||||
db.table('albums').where('id', file.albumid).update('editedAt', file.timestamp).then(() => {})
|
||||
.catch(error => { console.log(error); res.json({ success: false, description: 'Error updating album' }) })
|
||||
.catch(error => { console.log(error); res.json({ success: false, description: 'Error updating album.' }) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,7 +186,7 @@ uploadsController.delete = async (req, res) => {
|
||||
const user = await utils.authorize(req, res)
|
||||
const id = req.body.id
|
||||
if (id === undefined || id === '') {
|
||||
return res.json({ success: false, description: 'No file specified' })
|
||||
return res.json({ success: false, description: 'No file specified.' })
|
||||
}
|
||||
|
||||
const file = await db.table('files')
|
||||
@ -285,7 +288,7 @@ uploadsController.list = async (req, res) => {
|
||||
}
|
||||
|
||||
let ext = path.extname(file.name).toLowerCase()
|
||||
if ((config.uploads.generateImageThumbnails && utils.imageExtensions.includes(ext)) || (config.uploads.generateVideoThumbnails && utils.videoExtensions.includes(ext))) {
|
||||
if ((config.uploads.generateThumbnails.image && utils.imageExtensions.includes(ext)) || (config.uploads.generateThumbnails.video && utils.videoExtensions.includes(ext))) {
|
||||
file.thumb = `${basedomain}/thumbs/${file.name.slice(0, -ext.length)}.png`
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ utilsController.getPrettyDate = function (date) {
|
||||
|
||||
utilsController.authorize = async (req, res) => {
|
||||
const token = req.headers.token
|
||||
if (token === undefined) return res.status(401).json({ success: false, description: 'No token provided' })
|
||||
if (token === undefined) return res.status(401).json({ success: false, description: 'No token provided.' })
|
||||
|
||||
const user = await db.table('users').where('token', token).first()
|
||||
if (!user) return res.status(401).json({ success: false, description: 'Invalid token' })
|
||||
if (!user) return res.status(401).json({ success: false, description: 'Invalid token.' })
|
||||
return user
|
||||
}
|
||||
|
||||
@ -36,8 +36,8 @@ utilsController.generateThumbs = function (file, basedomain) {
|
||||
const isImageExt = utilsController.imageExtensions.includes(ext)
|
||||
|
||||
if (!isVideoExt && !isImageExt) return
|
||||
if (isVideoExt && config.uploads.generateVideoThumbnails !== true) return
|
||||
if (isImageExt && config.uploads.generateImageThumbnails !== true) return
|
||||
if (isVideoExt && config.uploads.generateThumbnails.video !== true) return
|
||||
if (isImageExt && config.uploads.generateThumbnails.image !== true) return
|
||||
|
||||
let thumbname = path.join(__dirname, '..', config.uploads.folder, 'thumbs', file.name.slice(0, -ext.length) + '.png')
|
||||
fs.access(thumbname, err => {
|
||||
|
@ -3,13 +3,10 @@ const db = require('knex')(config.database)
|
||||
|
||||
const migration = {}
|
||||
migration.start = async () => {
|
||||
await db.schema.table('albums', table => {
|
||||
table.dateTime('editedAt')
|
||||
table.dateTime('zipGeneratedAt')
|
||||
}).catch(() => {})
|
||||
await db.schema.table('users', table => {
|
||||
table.integer('enabled')
|
||||
}).catch(() => {})
|
||||
await db.schema.table('albums', t => t.dateTime('editedAt')).catch(err => console.warn(err.message))
|
||||
await db.schema.table('albums', t => t.dateTime('zipGeneratedAt')).catch(err => console.warn(err.message))
|
||||
await db.schema.table('users', t => t.dateTime('enabled')).catch(err => console.warn(err.message))
|
||||
await db.schema.table('users', t => t.dateTime('fileLength')).catch(err => console.warn(err.message))
|
||||
console.log('Migration finished! Now start lolisafe normally')
|
||||
process.exit(0)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
|
||||
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="js/album.js?v=V2RnA3Mwhh"></script>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="libs/fontello/fontello.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
|
||||
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="js/auth.js?v=V2RnA3Mwhh"></script>
|
||||
|
@ -12,8 +12,8 @@
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="libs/fontello/fontello.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="css/dashboard.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
|
||||
<link rel="stylesheet" type="text/css" href="css/dashboard.css?v=ugMWEbHDxs">
|
||||
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="js/dashboard.js?v=29qSkTNt9U"></script>
|
||||
@ -108,7 +108,10 @@
|
||||
<p class="menu-label">Administration</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<a id="itemTokens" onclick="panel.changeToken()">Change your token</a>
|
||||
<a id="itemFileLength" onclick="panel.changeFileLength()">Preferred file length</a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="itemTokens" onclick="panel.changeToken()">Manage your token</a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="itemPassword" onclick="panel.changePassword()">Change your password</a>
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
|
||||
|
||||
<!-- Open Graph tags -->
|
||||
<meta property="og:type" content="website" />
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
|
||||
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="libs/dropzone/dropzone.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
|
||||
|
@ -207,3 +207,7 @@ section#dashboard div#table div.column .title {
|
||||
line-height: 200px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.help {
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
@ -462,6 +462,63 @@ panel.getAlbum = function (item) {
|
||||
panel.getUploads(item.id)
|
||||
}
|
||||
|
||||
panel.changeFileLength = function () {
|
||||
axios.get('api/fileLength/config')
|
||||
.then(function (response) {
|
||||
if (response.data.success === false) {
|
||||
if (response.data.description === 'No token provided') return panel.verifyToken(panel.token)
|
||||
else return swal('An error occurred', response.data.description, 'error')
|
||||
}
|
||||
|
||||
panel.page.innerHTML = `
|
||||
<h2 class="subtitle">Preferred file length</h2>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Your current file length:</label>
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<input id="fileLength" class="input" type="text" placeholder="Your file length" value="${response.data.fileLength ? Math.min(Math.max(response.data.fileLength, response.data.config.min), response.data.config.max) : response.data.config.default}">
|
||||
</div>
|
||||
<div class="control">
|
||||
<a id="setFileLength" class="button is-primary">Set file length</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help">Default file length is <b>${response.data.config.default}</b> characters. ${response.data.config.userChangeable ? `Range allowed for user is <b>${response.data.config.min}</b> to <b>${response.data.config.max}</b> characters.` : 'Changing file length is disabled at the moment.'}</p>
|
||||
</div>
|
||||
`
|
||||
|
||||
document.getElementById('setFileLength').addEventListener('click', function () {
|
||||
panel.setFileLength(document.getElementById('fileLength').value)
|
||||
})
|
||||
})
|
||||
.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')
|
||||
})
|
||||
}
|
||||
|
||||
panel.setFileLength = function (fileLength) {
|
||||
axios.post('api/fileLength/change', { fileLength })
|
||||
.then(function (response) {
|
||||
if (response.data.success === false) {
|
||||
if (response.data.description === 'No token provided') return panel.verifyToken(panel.token)
|
||||
else return swal('An error occurred', response.data.description, 'error')
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Woohoo!',
|
||||
text: 'Your file length was successfully changed.',
|
||||
icon: 'success'
|
||||
}).then(() => {
|
||||
location.reload()
|
||||
})
|
||||
})
|
||||
.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')
|
||||
})
|
||||
}
|
||||
|
||||
panel.changeToken = function () {
|
||||
axios.get('api/tokens')
|
||||
.then(function (response) {
|
||||
@ -506,7 +563,7 @@ panel.getNewToken = function () {
|
||||
|
||||
swal({
|
||||
title: 'Woohoo!',
|
||||
text: 'Your token was changed successfully.',
|
||||
text: 'Your token was successfully changed.',
|
||||
icon: 'success'
|
||||
}).then(() => {
|
||||
localStorage.token = response.data.token
|
||||
@ -567,7 +624,7 @@ panel.sendNewPassword = function (pass) {
|
||||
|
||||
swal({
|
||||
title: 'Woohoo!',
|
||||
text: 'Your password was changed successfully.',
|
||||
text: 'Your password was successfully changed.',
|
||||
icon: 'success'
|
||||
}).then(() => {
|
||||
location.reload()
|
||||
|
@ -19,7 +19,7 @@ routes.get('/a/:identifier', async (req, res, next) => {
|
||||
file.file = `${basedomain}/${file.name}`
|
||||
|
||||
let ext = path.extname(file.name).toLowerCase()
|
||||
if ((config.uploads.generateImageThumbnails && utils.imageExtensions.includes(ext)) || (config.uploads.generateVideoThumbnails && utils.videoExtensions.includes(ext))) {
|
||||
if ((config.uploads.generateThumbnails.image && utils.imageExtensions.includes(ext)) || (config.uploads.generateThumbnails.video && utils.videoExtensions.includes(ext))) {
|
||||
file.thumb = `${basedomain}/thumbs/${file.name.slice(0, -ext.length)}.png`
|
||||
|
||||
/*
|
||||
|
@ -33,5 +33,7 @@ routes.get('/albums/test', (req, res, next) => albumsController.test(req, res, n
|
||||
routes.get('/tokens', (req, res, next) => tokenController.list(req, res, next))
|
||||
routes.post('/tokens/verify', (req, res, next) => tokenController.verify(req, res, next))
|
||||
routes.post('/tokens/change', (req, res, next) => tokenController.change(req, res, next))
|
||||
routes.get('/fileLength/config', (req, res, next) => authController.getFileLengthConfig(req, res, next))
|
||||
routes.post('/fileLength/change', (req, res, next) => authController.changeFileLength(req, res, next))
|
||||
|
||||
module.exports = routes
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- Stylesheets and scripts -->
|
||||
<link rel="stylesheet" type="text/css" href="../libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
|
||||
<link rel="stylesheet" type="text/css" href="../css/style.css?v=wtTfETVFNy">
|
||||
<link rel="stylesheet" type="text/css" href="../css/style.css?v=ugMWEbHDxs">
|
||||
<script type="text/javascript" src="../libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
|
||||
<script type="text/javascript" src="../libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user