diff --git a/config.sample.js b/config.sample.js
index 912265a..d5c65d2 100644
--- a/config.sample.js
+++ b/config.sample.js
@@ -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.
diff --git a/controllers/albumsController.js b/controllers/albumsController.js
index a07449a..d5331e6 100644
--- a/controllers/albumsController.js
+++ b/controllers/albumsController.js
@@ -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()
diff --git a/controllers/authController.js b/controllers/authController.js
index f54c5d3..c625c85 100644
--- a/controllers/authController.js
+++ b/controllers/authController.js
@@ -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
diff --git a/controllers/tokenController.js b/controllers/tokenController.js
index bb8f9c9..15b1d1c 100644
--- a/controllers/tokenController.js
+++ b/controllers/tokenController.js
@@ -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 })
 }
 
diff --git a/controllers/uploadController.js b/controllers/uploadController.js
index d924f4c..600a998 100644
--- a/controllers/uploadController.js
+++ b/controllers/uploadController.js
@@ -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`
     }
   }
diff --git a/controllers/utilsController.js b/controllers/utilsController.js
index 101932f..54f08db 100644
--- a/controllers/utilsController.js
+++ b/controllers/utilsController.js
@@ -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 => {
diff --git a/database/migration.js b/database/migration.js
index 0e0162e..4241d75 100644
--- a/database/migration.js
+++ b/database/migration.js
@@ -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)
 }
diff --git a/pages/album.html b/pages/album.html
index 4e1e68e..795c942 100644
--- a/pages/album.html
+++ b/pages/album.html
@@ -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>
diff --git a/pages/auth.html b/pages/auth.html
index 7188b8c..5f4104c 100644
--- a/pages/auth.html
+++ b/pages/auth.html
@@ -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>
diff --git a/pages/dashboard.html b/pages/dashboard.html
index a24068d..a22c939 100644
--- a/pages/dashboard.html
+++ b/pages/dashboard.html
@@ -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>
diff --git a/pages/faq.html b/pages/faq.html
index b559d0e..0d1ae87 100644
--- a/pages/faq.html
+++ b/pages/faq.html
@@ -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" />
diff --git a/pages/home.html b/pages/home.html
index 7cba7a1..daf513d 100644
--- a/pages/home.html
+++ b/pages/home.html
@@ -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>
diff --git a/public/css/style.css b/public/css/style.css
index ca13320..486aa7d 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -207,3 +207,7 @@ section#dashboard div#table div.column .title {
   line-height: 200px;
   font-weight: normal;
 }
+
+.help {
+  color: #7f8c8d;
+}
diff --git a/public/js/dashboard.js b/public/js/dashboard.js
index 9588da7..2799587 100644
--- a/public/js/dashboard.js
+++ b/public/js/dashboard.js
@@ -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()
diff --git a/routes/album.js b/routes/album.js
index d2a45eb..e68b736 100644
--- a/routes/album.js
+++ b/routes/album.js
@@ -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`
 
       /*
diff --git a/routes/api.js b/routes/api.js
index ae93e98..3e0e7ca 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -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
diff --git a/views/album.handlebars b/views/album.handlebars
index 4419496..f89b70f 100644
--- a/views/album.handlebars
+++ b/views/album.handlebars
@@ -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>