From ad852de51a0d2dd5d29c08838d5a430c58849e74 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 8 Jul 2020 04:00:12 +0300 Subject: [PATCH] chore: linter the entire project using the new rules --- knexfile.js | 10 +-- package.json | 3 +- pm2.json | 4 +- .../20190221225812_initialMigration.js | 22 ++--- src/api/database/seeds/initial.js | 5 +- src/api/databaseMigration.js | 35 ++++---- src/api/routes/admin/banIP.js | 2 +- src/api/routes/admin/fileGET.js | 2 +- src/api/routes/admin/unBanIP.js | 2 +- src/api/routes/admin/userDemote.js | 2 +- src/api/routes/admin/userDisable.js | 2 +- src/api/routes/admin/userEnable.js | 2 +- src/api/routes/admin/userGET.js | 2 +- src/api/routes/admin/userPromote.js | 2 +- src/api/routes/admin/userPurge.js | 2 +- src/api/routes/admin/usersGET.js | 2 +- src/api/routes/albums/albumDELETE.js | 1 - src/api/routes/albums/albumPOST.js | 4 +- src/api/routes/albums/albumZipGET.js | 10 +-- src/api/routes/albums/link/linkDELETE.js | 3 +- src/api/routes/albums/link/linkEditPOST.js | 3 +- src/api/routes/albums/link/linkPOST.js | 10 +-- src/api/routes/albums/link/linksGET.js | 2 +- src/api/routes/auth/loginPOST.js | 8 +- src/api/routes/auth/registerPOST.js | 8 +- src/api/routes/files/filesAlbumsGET.js | 4 +- src/api/routes/files/filesGET.js | 2 +- src/api/routes/files/tagAddPOST.js | 5 +- src/api/routes/service/configGET.js | 10 +-- src/api/routes/tags/tagPOST.js | 4 +- src/api/routes/tags/tagsGET.js | 3 +- src/api/routes/uploads/chunksPOST.js | 14 +-- src/api/routes/uploads/uploadPOST.js | 44 +++++----- src/api/routes/user/apiKey.js | 6 +- src/api/routes/user/changePasswordPOST.js | 6 +- src/api/routes/user/userGET.js | 4 +- src/api/routes/verifyGET.js | 4 +- src/api/structures/Route.js | 8 +- src/api/structures/Server.js | 1 + src/api/utils/Log.js | 6 -- src/api/utils/ThumbUtil.js | 14 ++- src/api/utils/Util.js | 4 +- src/api/utils/videoPreview/FragmentPreview.js | 7 +- .../videoPreview/FrameIntervalPreview.js | 13 +-- src/site/components/album/AlbumDetails.vue | 62 ++++++++------ src/site/components/album/AlbumEntry.vue | 41 +++++---- src/site/components/grid/Grid.vue | 4 +- src/site/components/loading/CubeShadow.vue | 17 ++-- src/site/components/loading/Origami.vue | 18 ++-- src/site/components/loading/PingPong.vue | 26 +++--- src/site/components/loading/RotateSquare.vue | 13 +-- src/site/components/uploader/Uploader.vue | 1 + src/site/layouts/default.vue | 23 ++--- src/site/layouts/error.vue | 2 +- src/site/middleware/admin.js | 3 +- src/site/middleware/auth.js | 3 +- src/site/pages/dashboard/admin/file/_id.vue | 82 +++++++++++------- src/site/pages/dashboard/admin/settings.vue | 85 ++++++++++++------- src/site/pages/dashboard/tags/index.vue | 43 ++++++---- src/site/pages/faq.vue | 23 +++-- src/site/pages/index.vue | 1 + src/site/pages/register.vue | 37 +++++--- src/site/plugins/axios.js | 12 +-- src/site/plugins/flexsearch.js | 5 +- src/site/plugins/nuxt-client-init.js | 2 +- src/site/plugins/vue-isyourpasswordsafe.js | 2 +- src/site/plugins/vue-timeago.js | 2 +- src/site/store/auth.js | 4 + yarn.lock | 59 ++++++++++++- 69 files changed, 527 insertions(+), 350 deletions(-) diff --git a/knexfile.js b/knexfile.js index 2b75f3b..bfdb4ee 100644 --- a/knexfile.js +++ b/knexfile.js @@ -7,17 +7,17 @@ module.exports = { user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, - filename: 'database.sqlite' + filename: 'database.sqlite', }, pool: { min: process.env.DATABASE_POOL_MIN || 2, - max: process.env.DATABASE_POOL_MAX || 10 + max: process.env.DATABASE_POOL_MAX || 10, }, migrations: { - directory: 'src/api/database/migrations' + directory: 'src/api/database/migrations', }, seeds: { - directory: 'src/api/database/seeds' + directory: 'src/api/database/seeds', }, - useNullAsDefault: process.env.DB_CLIENT === 'sqlite3' ? true : false + useNullAsDefault: process.env.DB_CLIENT === 'sqlite3', }; diff --git a/package.json b/package.json index ce4d63b..aad96b4 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,8 @@ ], "import/no-extraneous-dependencies": "off", "no-restricted-syntax": "off", - "no-continue": "off" + "no-continue": "off", + "no-await-in-loop": "off" }, "settings": { "import/resolver": { diff --git a/pm2.json b/pm2.json index 57c3598..ae34600 100644 --- a/pm2.json +++ b/pm2.json @@ -1,5 +1,5 @@ { - "apps" : [ + "apps": [ { "name": "lolisafe", "script": "npm", @@ -7,7 +7,7 @@ "env": { "NODE_ENV": "production" }, - "env_production" : { + "env_production": { "NODE_ENV": "production" } } diff --git a/src/api/database/migrations/20190221225812_initialMigration.js b/src/api/database/migrations/20190221225812_initialMigration.js index 4bcea8d..dd18ee5 100644 --- a/src/api/database/migrations/20190221225812_initialMigration.js +++ b/src/api/database/migrations/20190221225812_initialMigration.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('users', table => { +exports.up = async (knex) => { + await knex.schema.createTable('users', (table) => { table.increments(); table.string('username'); table.text('password'); @@ -12,7 +12,7 @@ exports.up = async knex => { table.timestamp('editedAt'); }); - await knex.schema.createTable('albums', table => { + await knex.schema.createTable('albums', (table) => { table.increments(); table.integer('userId'); table.string('name'); @@ -22,7 +22,7 @@ exports.up = async knex => { table.timestamp('editedAt'); }); - await knex.schema.createTable('files', table => { + await knex.schema.createTable('files', (table) => { table.increments(); table.integer('userId'); table.string('name'); @@ -36,7 +36,7 @@ exports.up = async knex => { table.timestamp('editedAt'); }); - await knex.schema.createTable('links', table => { + await knex.schema.createTable('links', (table) => { table.increments(); table.integer('userId'); table.integer('albumId'); @@ -49,19 +49,19 @@ exports.up = async knex => { table.timestamp('editedAt'); }); - await knex.schema.createTable('albumsFiles', table => { + await knex.schema.createTable('albumsFiles', (table) => { table.increments(); table.integer('albumId'); table.integer('fileId'); }); - await knex.schema.createTable('albumsLinks', table => { + await knex.schema.createTable('albumsLinks', (table) => { table.increments(); table.integer('albumId'); table.integer('linkId'); }); - await knex.schema.createTable('tags', table => { + await knex.schema.createTable('tags', (table) => { table.increments(); table.string('uuid'); table.integer('userId'); @@ -70,19 +70,19 @@ exports.up = async knex => { table.timestamp('editedAt'); }); - await knex.schema.createTable('fileTags', table => { + await knex.schema.createTable('fileTags', (table) => { table.increments(); table.integer('fileId'); table.integer('tagId'); }); - await knex.schema.createTable('bans', table => { + await knex.schema.createTable('bans', (table) => { table.increments(); table.string('ip'); table.timestamp('createdAt'); }); }; -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTableIfExists('users'); await knex.schema.dropTableIfExists('albums'); await knex.schema.dropTableIfExists('files'); diff --git a/src/api/database/seeds/initial.js b/src/api/database/seeds/initial.js index 280fd74..cdbfa80 100644 --- a/src/api/database/seeds/initial.js +++ b/src/api/database/seeds/initial.js @@ -1,7 +1,8 @@ +/* eslint-disable no-console */ const bcrypt = require('bcrypt'); const moment = require('moment'); -exports.seed = async db => { +exports.seed = async (db) => { const now = moment.utc().toDate(); const user = await db.table('users').where({ username: process.env.ADMIN_ACCOUNT }).first(); if (user) return; @@ -14,7 +15,7 @@ exports.seed = async db => { createdAt: now, editedAt: now, enabled: true, - isAdmin: true + isAdmin: true, }); console.log(); console.log('========================================================='); diff --git a/src/api/databaseMigration.js b/src/api/databaseMigration.js index 5cf4b39..d95605d 100644 --- a/src/api/databaseMigration.js +++ b/src/api/databaseMigration.js @@ -1,28 +1,31 @@ +/* eslint-disable eqeqeq */ +/* eslint-disable no-await-in-loop */ +/* eslint-disable no-console */ const nodePath = require('path'); const moment = require('moment'); const oldDb = require('knex')({ client: 'sqlite3', connection: { - filename: nodePath.join(__dirname, '..', '..', 'db') + filename: nodePath.join(__dirname, '..', '..', 'db'), }, - useNullAsDefault: true + useNullAsDefault: true, }); const newDb = require('knex')({ client: 'sqlite3', connection: { - filename: nodePath.join(__dirname, '..', '..', 'database.sqlite') + filename: nodePath.join(__dirname, '..', '..', 'database.sqlite'), }, - postProcessResponse: result => { + postProcessResponse: (result) => { const booleanFields = [ 'enabled', 'enableDownload', - 'isAdmin' + 'isAdmin', ]; - const processResponse = row => { - Object.keys(row).forEach(key => { + const processResponse = (row) => { + Object.keys(row).forEach((key) => { if (booleanFields.includes(key)) { if (row[key] === 0) row[key] = false; else if (row[key] === 1) row[key] = true; @@ -31,11 +34,11 @@ const newDb = require('knex')({ return row; }; - if (Array.isArray(result)) return result.map(row => processResponse(row)); + if (Array.isArray(result)) return result.map((row) => processResponse(row)); if (typeof result === 'object') return processResponse(result); return result; }, - useNullAsDefault: true + useNullAsDefault: true, }); const start = async () => { @@ -49,13 +52,13 @@ const start = async () => { id: user.id, username: user.username, password: user.password, - enabled: user.enabled == 1 ? true : false, + enabled: user.enabled == 1, isAdmin: false, apiKey: user.token, passwordEditedAt: now, apiKeyEditedAt: now, createdAt: now, - editedAt: now + editedAt: now, }; await newDb.table('users').insert(userToInsert); } @@ -71,7 +74,7 @@ const start = async () => { name: album.name, zippedAt: album.zipGeneratedAt ? moment.unix(album.zipGeneratedAt).toDate() : null, createdAt: moment.unix(album.timestamp).toDate(), - editedAt: moment.unix(album.editedAt).toDate() + editedAt: moment.unix(album.editedAt).toDate(), }; const linkToInsert = { userId: album.userid, @@ -81,13 +84,13 @@ const start = async () => { enabled: true, enableDownload: true, createdAt: now, - editedAt: now + editedAt: now, }; await newDb.table('albums').insert(albumToInsert); const insertedId = await newDb.table('links').insert(linkToInsert); await newDb.table('albumsLinks').insert({ albumId: album.id, - linkId: insertedId[0] + linkId: insertedId[0], }); } console.log('Finished migrating albums...'); @@ -106,12 +109,12 @@ const start = async () => { hash: file.hash, ip: file.ip, createdAt: moment.unix(file.timestamp).toDate(), - editedAt: moment.unix(file.timestamp).toDate() + editedAt: moment.unix(file.timestamp).toDate(), }; filesToInsert.push(fileToInsert); albumsFilesToInsert.push({ albumId: file.albumid, - fileId: file.id + fileId: file.id, }); } await newDb.batchInsert('files', filesToInsert, 20); diff --git a/src/api/routes/admin/banIP.js b/src/api/routes/admin/banIP.js index 692880d..4dfe03c 100644 --- a/src/api/routes/admin/banIP.js +++ b/src/api/routes/admin/banIP.js @@ -17,7 +17,7 @@ class banIP extends Route { } return res.json({ - message: 'Successfully banned the ip' + message: 'Successfully banned the ip', }); } } diff --git a/src/api/routes/admin/fileGET.js b/src/api/routes/admin/fileGET.js index 3bb8da4..0d1b147 100644 --- a/src/api/routes/admin/fileGET.js +++ b/src/api/routes/admin/fileGET.js @@ -21,7 +21,7 @@ class filesGET extends Route { return res.json({ message: 'Successfully retrieved file', file, - user + user, }); } } diff --git a/src/api/routes/admin/unBanIP.js b/src/api/routes/admin/unBanIP.js index 493834b..725468c 100644 --- a/src/api/routes/admin/unBanIP.js +++ b/src/api/routes/admin/unBanIP.js @@ -19,7 +19,7 @@ class unBanIP extends Route { } return res.json({ - message: 'Successfully unbanned the ip' + message: 'Successfully unbanned the ip', }); } } diff --git a/src/api/routes/admin/userDemote.js b/src/api/routes/admin/userDemote.js index b430a48..3f6623d 100644 --- a/src/api/routes/admin/userDemote.js +++ b/src/api/routes/admin/userDemote.js @@ -20,7 +20,7 @@ class userDemote extends Route { } return res.json({ - message: 'Successfully demoted user' + message: 'Successfully demoted user', }); } } diff --git a/src/api/routes/admin/userDisable.js b/src/api/routes/admin/userDisable.js index e39c811..029e4af 100644 --- a/src/api/routes/admin/userDisable.js +++ b/src/api/routes/admin/userDisable.js @@ -20,7 +20,7 @@ class userDisable extends Route { } return res.json({ - message: 'Successfully disabled user' + message: 'Successfully disabled user', }); } } diff --git a/src/api/routes/admin/userEnable.js b/src/api/routes/admin/userEnable.js index cff622f..aca7a0b 100644 --- a/src/api/routes/admin/userEnable.js +++ b/src/api/routes/admin/userEnable.js @@ -20,7 +20,7 @@ class userEnable extends Route { } return res.json({ - message: 'Successfully enabled user' + message: 'Successfully enabled user', }); } } diff --git a/src/api/routes/admin/userGET.js b/src/api/routes/admin/userGET.js index 14a6c92..30c79f4 100644 --- a/src/api/routes/admin/userGET.js +++ b/src/api/routes/admin/userGET.js @@ -23,7 +23,7 @@ class usersGET extends Route { return res.json({ message: 'Successfully retrieved user', user, - files + files, }); } catch (error) { return super.error(res, error); diff --git a/src/api/routes/admin/userPromote.js b/src/api/routes/admin/userPromote.js index 4a5ed88..3e14cb7 100644 --- a/src/api/routes/admin/userPromote.js +++ b/src/api/routes/admin/userPromote.js @@ -20,7 +20,7 @@ class userPromote extends Route { } return res.json({ - message: 'Successfully promoted user' + message: 'Successfully promoted user', }); } } diff --git a/src/api/routes/admin/userPurge.js b/src/api/routes/admin/userPurge.js index 90f6ec9..8f61ff9 100644 --- a/src/api/routes/admin/userPurge.js +++ b/src/api/routes/admin/userPurge.js @@ -18,7 +18,7 @@ class userDemote extends Route { } return res.json({ - message: 'Successfully deleted the user\'s files' + message: 'Successfully deleted the user\'s files', }); } } diff --git a/src/api/routes/admin/usersGET.js b/src/api/routes/admin/usersGET.js index 52a707f..4e9b954 100644 --- a/src/api/routes/admin/usersGET.js +++ b/src/api/routes/admin/usersGET.js @@ -12,7 +12,7 @@ class usersGET extends Route { return res.json({ message: 'Successfully retrieved users', - users + users, }); } catch (error) { return super.error(res, error); diff --git a/src/api/routes/albums/albumDELETE.js b/src/api/routes/albums/albumDELETE.js index 4e6640e..f9c22e6 100644 --- a/src/api/routes/albums/albumDELETE.js +++ b/src/api/routes/albums/albumDELETE.js @@ -1,5 +1,4 @@ const Route = require('../../structures/Route'); -const Util = require('../../utils/Util'); class albumDELETE extends Route { constructor() { diff --git a/src/api/routes/albums/albumPOST.js b/src/api/routes/albums/albumPOST.js index 841da3d..94ee8a7 100644 --- a/src/api/routes/albums/albumPOST.js +++ b/src/api/routes/albums/albumPOST.js @@ -1,5 +1,5 @@ -const Route = require('../../structures/Route'); const moment = require('moment'); +const Route = require('../../structures/Route'); class albumPOST extends Route { constructor() { @@ -25,7 +25,7 @@ class albumPOST extends Route { name, userId: user.id, createdAt: now, - editedAt: now + editedAt: now, }; const dbRes = await db.table('albums').insert(insertObj); diff --git a/src/api/routes/albums/albumZipGET.js b/src/api/routes/albums/albumZipGET.js index a6ef6fd..bd74ef3 100644 --- a/src/api/routes/albums/albumZipGET.js +++ b/src/api/routes/albums/albumZipGET.js @@ -1,8 +1,8 @@ +const path = require('path'); +const jetpack = require('fs-jetpack'); const Route = require('../../structures/Route'); const Util = require('../../utils/Util'); const log = require('../../utils/Log'); -const path = require('path'); -const jetpack = require('fs-jetpack'); class albumGET extends Route { constructor() { @@ -21,7 +21,7 @@ class albumGET extends Route { .where({ identifier, enabled: true, - enableDownload: true + enableDownload: true, }) .first(); if (!link) return res.status(400).json({ message: 'The supplied identifier could not be found' }); @@ -64,11 +64,11 @@ class albumGET extends Route { /* Get the actual files */ - const fileIds = fileList.map(el => el.fileId); + const fileIds = fileList.map((el) => el.fileId); const files = await db.table('files') .whereIn('id', fileIds) .select('name'); - const filesToZip = files.map(el => el.name); + const filesToZip = files.map((el) => el.name); try { Util.createZip(filesToZip, album); diff --git a/src/api/routes/albums/link/linkDELETE.js b/src/api/routes/albums/link/linkDELETE.js index b02d0b4..0381b50 100644 --- a/src/api/routes/albums/link/linkDELETE.js +++ b/src/api/routes/albums/link/linkDELETE.js @@ -1,5 +1,4 @@ const Route = require('../../../structures/Route'); -const { dump } = require('dumper.js'); class linkDELETE extends Route { constructor() { @@ -28,7 +27,7 @@ class linkDELETE extends Route { } return res.json({ - message: 'Successfully deleted link' + message: 'Successfully deleted link', }); } } diff --git a/src/api/routes/albums/link/linkEditPOST.js b/src/api/routes/albums/link/linkEditPOST.js index 0c7233b..4e0e0e1 100644 --- a/src/api/routes/albums/link/linkEditPOST.js +++ b/src/api/routes/albums/link/linkEditPOST.js @@ -1,5 +1,4 @@ const Route = require('../../../structures/Route'); -const log = require('../../../utils/Log'); class linkEditPOST extends Route { constructor() { @@ -23,7 +22,7 @@ class linkEditPOST extends Route { try { const updateObj = { enableDownload: enableDownload || false, - expiresAt // This one should be null if not supplied + expiresAt, // This one should be null if not supplied }; await db .table('links') diff --git a/src/api/routes/albums/link/linkPOST.js b/src/api/routes/albums/link/linkPOST.js index 7ecc5cb..d58598a 100644 --- a/src/api/routes/albums/link/linkPOST.js +++ b/src/api/routes/albums/link/linkPOST.js @@ -28,15 +28,13 @@ class linkPOST extends Route { .where('albumId', albumId) .count({ count: 'id' }) .first(); - if (count >= parseInt(process.env.MAX_LINKS_PER_ALBUM, 10)) - return res.status(400).json({ message: 'Maximum links per album reached' }); + if (count >= parseInt(process.env.MAX_LINKS_PER_ALBUM, 10)) return res.status(400).json({ message: 'Maximum links per album reached' }); /* Try to allocate a new identifier on the db */ const identifier = await Util.getUniqueAlbumIdentifier(); - if (!identifier) - return res.status(500).json({ message: 'There was a problem allocating a link for your album' }); + if (!identifier) return res.status(500).json({ message: 'There was a problem allocating a link for your album' }); try { const insertObj = { @@ -46,13 +44,13 @@ class linkPOST extends Route { enabled: true, enableDownload: true, expiresAt: null, - views: 0 + views: 0, }; await db.table('links').insert(insertObj); return res.json({ message: 'The link was created successfully', - data: insertObj + data: insertObj, }); } catch (error) { return super.error(res, error); diff --git a/src/api/routes/albums/link/linksGET.js b/src/api/routes/albums/link/linksGET.js index edab49a..4487c26 100644 --- a/src/api/routes/albums/link/linksGET.js +++ b/src/api/routes/albums/link/linksGET.js @@ -14,7 +14,7 @@ class linkPOST extends Route { return res.json({ message: 'Successfully retrieved links', - links + links, }); } } diff --git a/src/api/routes/auth/loginPOST.js b/src/api/routes/auth/loginPOST.js index 205737a..5c7730c 100644 --- a/src/api/routes/auth/loginPOST.js +++ b/src/api/routes/auth/loginPOST.js @@ -1,7 +1,7 @@ -const Route = require('../../structures/Route'); const bcrypt = require('bcrypt'); const moment = require('moment'); const JWT = require('jsonwebtoken'); +const Route = require('../../structures/Route'); class loginPOST extends Route { constructor() { @@ -36,7 +36,7 @@ class loginPOST extends Route { const jwt = JWT.sign({ iss: 'lolisafe', sub: user.id, - iat: moment.utc().valueOf() + iat: moment.utc().valueOf(), }, process.env.SECRET, { expiresIn: '30d' }); return res.json({ @@ -45,10 +45,10 @@ class loginPOST extends Route { id: user.id, username: user.username, apiKey: user.apiKey, - isAdmin: user.isAdmin + isAdmin: user.isAdmin, }, token: jwt, - apiKey: user.apiKey + apiKey: user.apiKey, }); } } diff --git a/src/api/routes/auth/registerPOST.js b/src/api/routes/auth/registerPOST.js index feeb360..e2ac018 100644 --- a/src/api/routes/auth/registerPOST.js +++ b/src/api/routes/auth/registerPOST.js @@ -1,7 +1,7 @@ -const Route = require('../../structures/Route'); -const log = require('../../utils/Log'); const bcrypt = require('bcrypt'); const moment = require('moment'); +const Route = require('../../structures/Route'); +const log = require('../../utils/Log'); class registerPOST extends Route { constructor() { @@ -9,7 +9,7 @@ class registerPOST extends Route { } async run(req, res, db) { - if (process.env.USER_ACCOUNTS == 'false') return res.status(401).json({ message: 'Creation of new accounts is currently disabled' }); + if (process.env.USER_ACCOUNTS === 'false') return res.status(401).json({ message: 'Creation of new accounts is currently disabled' }); if (!req.body) return res.status(400).json({ message: 'No body provided' }); const { username, password } = req.body; if (!username || !password) return res.status(401).json({ message: 'Invalid body provided' }); @@ -50,7 +50,7 @@ class registerPOST extends Route { createdAt: now, editedAt: now, enabled: true, - isAdmin: false + isAdmin: false, }); return res.json({ message: 'The account was created successfully' }); } diff --git a/src/api/routes/files/filesAlbumsGET.js b/src/api/routes/files/filesAlbumsGET.js index 7f1190c..f5f2f3b 100644 --- a/src/api/routes/files/filesAlbumsGET.js +++ b/src/api/routes/files/filesAlbumsGET.js @@ -18,7 +18,7 @@ class filesGET extends Route { .select('albumId'); if (albumFiles.length) { - albumFiles = albumFiles.map(a => a.albumId); + albumFiles = albumFiles.map((a) => a.albumId); albums = await db.table('albums') .whereIn('id', albumFiles) .select('id', 'name'); @@ -26,7 +26,7 @@ class filesGET extends Route { return res.json({ message: 'Successfully retrieved file albums', - albums + albums, }); } } diff --git a/src/api/routes/files/filesGET.js b/src/api/routes/files/filesGET.js index 9e90633..ce1d788 100644 --- a/src/api/routes/files/filesGET.js +++ b/src/api/routes/files/filesGET.js @@ -36,7 +36,7 @@ class filesGET extends Route { return res.json({ message: 'Successfully retrieved files', files, - count + count, }); } } diff --git a/src/api/routes/files/tagAddPOST.js b/src/api/routes/files/tagAddPOST.js index 25467ab..07ecb18 100644 --- a/src/api/routes/files/tagAddPOST.js +++ b/src/api/routes/files/tagAddPOST.js @@ -14,7 +14,8 @@ class tagAddPOST extends Route { const file = await db.table('files').where({ id: fileId, userId: user.id }).first(); if (!file) return res.status(400).json({ message: 'File doesn\'t exist.' }); - tagNames.forEach(async tag => { + // eslint-disable-next-line consistent-return + tagNames.forEach(async (tag) => { try { await db.table('fileTags').insert({ fileId, tag }); } catch (error) { @@ -23,7 +24,7 @@ class tagAddPOST extends Route { }); return res.json({ - message: 'Successfully added file to album' + message: 'Successfully added file to album', }); } } diff --git a/src/api/routes/service/configGET.js b/src/api/routes/service/configGET.js index b653066..3c6a2f8 100644 --- a/src/api/routes/service/configGET.js +++ b/src/api/routes/service/configGET.js @@ -15,11 +15,11 @@ class configGET extends Route { maxUploadSize: parseInt(process.env.MAX_SIZE, 10), filenameLength: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10), albumLinkLength: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10), - generateThumbnails: process.env.GENERATE_THUMBNAILS == 'true' ? true : false, - generateZips: process.env.GENERATE_ZIPS == 'true' ? true : false, - publicMode: process.env.PUBLIC_MODE == 'true' ? true : false, - enableAccounts: process.env.USER_ACCOUNTS == 'true' ? true : false - } + generateThumbnails: process.env.GENERATE_THUMBNAILS === 'true', + generateZips: process.env.GENERATE_ZIPS === 'true', + publicMode: process.env.PUBLIC_MODE === 'true', + enableAccounts: process.env.USER_ACCOUNTS === 'true', + }, }); } } diff --git a/src/api/routes/tags/tagPOST.js b/src/api/routes/tags/tagPOST.js index b6ec395..856e0d4 100644 --- a/src/api/routes/tags/tagPOST.js +++ b/src/api/routes/tags/tagPOST.js @@ -1,5 +1,5 @@ -const Route = require('../../structures/Route'); const moment = require('moment'); +const Route = require('../../structures/Route'); class tagPOST extends Route { constructor() { @@ -22,7 +22,7 @@ class tagPOST extends Route { name, userId: user.id, createdAt: now, - editedAt: now + editedAt: now, }); return res.json({ message: 'The tag was created successfully' }); diff --git a/src/api/routes/tags/tagsGET.js b/src/api/routes/tags/tagsGET.js index 871148e..848e08d 100644 --- a/src/api/routes/tags/tagsGET.js +++ b/src/api/routes/tags/tagsGET.js @@ -1,5 +1,4 @@ const Route = require('../../structures/Route'); -const Util = require('../../utils/Util'); class tagsGET extends Route { constructor() { @@ -20,7 +19,7 @@ class tagsGET extends Route { return res.json({ message: 'Successfully retrieved tags', - tags + tags, }); } catch (error) { return super.error(res, error); diff --git a/src/api/routes/uploads/chunksPOST.js b/src/api/routes/uploads/chunksPOST.js index 013c0d6..a9baf55 100644 --- a/src/api/routes/uploads/chunksPOST.js +++ b/src/api/routes/uploads/chunksPOST.js @@ -1,27 +1,27 @@ -const Route = require('../../structures/Route'); const path = require('path'); -const Util = require('../../utils/Util'); const jetpack = require('fs-jetpack'); const randomstring = require('randomstring'); +const Util = require('../../utils/Util'); +const Route = require('../../structures/Route'); class uploadPOST extends Route { constructor() { super('/upload/chunks', 'post', { bypassAuth: true, - canApiKey: true + canApiKey: true, }); } - async run(req, res, db) { + async run(req, res) { const filename = Util.getUniqueFilename(randomstring.generate(32)); // console.log('Files', req.body.files); const info = { size: req.body.files[0].size, - url: `${process.env.DOMAIN}/` + url: `${process.env.DOMAIN}/`, }; for (const chunk of req.body.files) { - const { uuid, count } = chunk; + const { uuid } = chunk; // console.log('Chunk', chunk); const chunkOutput = path.join(__dirname, @@ -65,7 +65,7 @@ class uploadPOST extends Route { return res.status(201).send({ message: 'Sucessfully merged the chunk(s).', - ...info + ...info, /* name: `${filename}${ext || ''}`, size: exists.size, diff --git a/src/api/routes/uploads/uploadPOST.js b/src/api/routes/uploads/uploadPOST.js index 6c01dd3..48fc592 100644 --- a/src/api/routes/uploads/uploadPOST.js +++ b/src/api/routes/uploads/uploadPOST.js @@ -1,17 +1,18 @@ -const Route = require('../../structures/Route'); const path = require('path'); -const Util = require('../../utils/Util'); const jetpack = require('fs-jetpack'); const multer = require('multer'); const moment = require('moment'); +const Util = require('../../utils/Util'); +const Route = require('../../structures/Route'); + const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: parseInt(process.env.MAX_SIZE, 10) * (1000 * 1000), - files: 1 + files: 1, }, - fileFilter: (req, file, cb) => { - // TODO: Enable blacklisting of files/extensions + fileFilter: (req, file, cb) => + // TODO: Enable blacklisting of files/extensions /* if (options.blacklist.mimes.includes(file.mimetype)) { return cb(new Error(`${file.mimetype} is a blacklisted filetype.`)); @@ -19,35 +20,34 @@ const upload = multer({ return cb(new Error(`${path.extname(file.originalname).toLowerCase()} is a blacklisted extension.`)); } */ - return cb(null, true); - } + cb(null, true) + , }).array('files[]'); /* TODO: If source has transparency generate a png thumbnail, otherwise a jpg. TODO: If source is a gif, generate a thumb of the first frame and play the gif on hover on the frontend. - TODO: If source is a video, generate a thumb of the first frame and save the video length to the file? - Another possible solution would be to play a gif on hover that grabs a few chunks like youtube. TODO: Think if its worth making a folder with the user uuid in uploads/ and upload the pictures there so that this way at least not every single file will be in 1 directory - - Addendum to this: Now that the default behaviour is to serve files with node, we can actually pull this off. Before this, having files in - subfolders meant messing with nginx and the paths, but now it should be fairly easy to re-arrange the folder structure with express.static - I see great value in this, open to suggestions. + XXX: Now that the default behaviour is to serve files with node, we can actually pull this off. + Before this, having files in subfolders meant messing with nginx and the paths, + but now it should be fairly easy to re-arrange the folder structure with express.static + I see great value in this, open to suggestions. */ class uploadPOST extends Route { constructor() { super('/upload', 'post', { bypassAuth: true, - canApiKey: true + canApiKey: true, }); } async run(req, res, db) { const user = await Util.isAuthorized(req); - if (!user && process.env.PUBLIC_MODE == 'false') return res.status(401).json({ message: 'Not authorized to use this resource' }); + if (!user && process.env.PUBLIC_MODE === 'false') return res.status(401).json({ message: 'Not authorized to use this resource' }); const albumId = req.body.albumid || req.headers.albumid; if (albumId && !user) return res.status(401).json({ message: 'Only registered users can upload files to an album' }); @@ -56,12 +56,13 @@ class uploadPOST extends Route { if (!album) return res.status(401).json({ message: 'Album doesn\'t exist or it doesn\'t belong to the user' }); } - return upload(req, res, async err => { + return upload(req, res, async (err) => { if (err) console.error(err.message); let uploadedFile = {}; let insertedId; + // eslint-disable-next-line no-underscore-dangle const remappedKeys = this._remapKeys(req.body); const file = req.files[0]; @@ -105,7 +106,7 @@ class uploadPOST extends Route { name: filename, hash, size: file.buffer.length, - url: filename + url: filename, }; } @@ -124,7 +125,7 @@ class uploadPOST extends Route { return res.status(201).send({ message: 'Sucessfully uploaded the file.', - ...uploadedFile + ...uploadedFile, }); }); } @@ -137,7 +138,7 @@ class uploadPOST extends Route { size: exists.size, url: `${process.env.DOMAIN}/${exists.name}`, deleteUrl: `${process.env.DOMAIN}/api/file/${exists.id}`, - repeated: true + repeated: true, }); return Util.deleteFile(filename); @@ -145,7 +146,7 @@ class uploadPOST extends Route { async checkIfFileExists(db, user, hash) { const exists = await db.table('files') - .where(function() { // eslint-disable-line func-names + .where(function () { // eslint-disable-line func-names if (user) this.where('userId', user.id); else this.whereNull('userId'); }) @@ -186,7 +187,7 @@ class uploadPOST extends Route { hash: file.hash, ip: req.ip, createdAt: now, - editedAt: now + editedAt: now, }); } else { insertedId = await db.table('files').insert({ @@ -198,7 +199,7 @@ class uploadPOST extends Route { hash: file.hash, ip: req.ip, createdAt: now, - editedAt: now + editedAt: now, }, 'id'); } return insertedId; @@ -220,6 +221,7 @@ class uploadPOST extends Route { } return body; } + return keys; } } diff --git a/src/api/routes/user/apiKey.js b/src/api/routes/user/apiKey.js index a87d98d..a63f0c0 100644 --- a/src/api/routes/user/apiKey.js +++ b/src/api/routes/user/apiKey.js @@ -1,7 +1,7 @@ -const Route = require('../../structures/Route'); const randomstring = require('randomstring'); const moment = require('moment'); const { dump } = require('dumper.js'); +const Route = require('../../structures/Route'); class apiKeyPOST extends Route { constructor() { @@ -17,7 +17,7 @@ class apiKeyPOST extends Route { .where({ id: user.id }) .update({ apiKey, - apiKeyEditedAt: now + apiKeyEditedAt: now, }); } catch (error) { dump(error); @@ -26,7 +26,7 @@ class apiKeyPOST extends Route { return res.json({ message: 'Successfully created new api key', - apiKey + apiKey, }); } } diff --git a/src/api/routes/user/changePasswordPOST.js b/src/api/routes/user/changePasswordPOST.js index 9cd621e..1b3a27a 100644 --- a/src/api/routes/user/changePasswordPOST.js +++ b/src/api/routes/user/changePasswordPOST.js @@ -1,7 +1,7 @@ -const Route = require('../../structures/Route'); -const log = require('../../utils/Log'); const bcrypt = require('bcrypt'); const moment = require('moment'); +const Route = require('../../structures/Route'); +const log = require('../../utils/Log'); class changePasswordPOST extends Route { constructor() { @@ -36,7 +36,7 @@ class changePasswordPOST extends Route { const now = moment.utc().toDate(); await db.table('users').where('id', user.id).update({ password: hash, - passwordEditedAt: now + passwordEditedAt: now, }); return res.json({ message: 'The password was changed successfully' }); diff --git a/src/api/routes/user/userGET.js b/src/api/routes/user/userGET.js index 7929aac..6f179a9 100644 --- a/src/api/routes/user/userGET.js +++ b/src/api/routes/user/userGET.js @@ -12,8 +12,8 @@ class usersGET extends Route { id: user.id, username: user.username, isAdmin: user.isAdmin, - apiKey: user.apiKey - } + apiKey: user.apiKey, + }, }); } } diff --git a/src/api/routes/verifyGET.js b/src/api/routes/verifyGET.js index 2f370e8..107c20a 100644 --- a/src/api/routes/verifyGET.js +++ b/src/api/routes/verifyGET.js @@ -11,8 +11,8 @@ class verifyGET extends Route { user: { id: user.id, username: user.username, - isAdmin: user.isAdmin - } + isAdmin: user.isAdmin, + }, }); } } diff --git a/src/api/structures/Route.js b/src/api/structures/Route.js index c2ad32e..400ae3d 100644 --- a/src/api/structures/Route.js +++ b/src/api/structures/Route.js @@ -55,7 +55,8 @@ class Route { if (banned) return res.status(401).json({ message: 'This IP has been banned from using the service.' }); if (this.options.bypassAuth) return this.run(req, res, db); - // The only reason I call it token here and not Api Key is to be backwards compatible with the uploader and sharex + // The only reason I call it token here and not Api Key is to be backwards compatible + // with the uploader and sharex // Small price to pay. if (req.headers.token) return this.authorizeApiKey(req, res, req.headers.token); if (!req.headers.authorization) return res.status(401).json({ message: 'No authorization header provided' }); @@ -96,10 +97,7 @@ class Route { return this.run(req, res, db, user); } - run(req, res, db) { - // eslint-disable-line no-unused-vars - - } + run() {} error(res, error) { log.error(error); diff --git a/src/api/structures/Server.js b/src/api/structures/Server.js index 5d2290b..c8537fb 100644 --- a/src/api/structures/Server.js +++ b/src/api/structures/Server.js @@ -11,6 +11,7 @@ const morgan = require('morgan'); const log = require('../utils/Log'); const ThumbUtil = require('../utils/ThumbUtil'); +// eslint-disable-next-line no-unused-vars const rateLimiter = new RateLimit({ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW, 10), max: parseInt(process.env.RATE_LIMIT_MAX, 10), diff --git a/src/api/utils/Log.js b/src/api/utils/Log.js index 8b38c2b..99d11e4 100644 --- a/src/api/utils/Log.js +++ b/src/api/utils/Log.js @@ -27,12 +27,6 @@ class Log { else console.log(chalk.gray(args)); // eslint-disable-line no-console } - /* - static dump(args) { - dump(args); - } - */ - static checkIfArrayOrObject(thing) { if (typeof thing === typeof [] || typeof thing === typeof {}) return true; return false; diff --git a/src/api/utils/ThumbUtil.js b/src/api/utils/ThumbUtil.js index f8c73e7..98ba5c0 100644 --- a/src/api/utils/ThumbUtil.js +++ b/src/api/utils/ThumbUtil.js @@ -22,7 +22,9 @@ class ThumbUtil { const output = `${filename.slice(0, -ext.length)}.png`; const previewOutput = `${filename.slice(0, -ext.length)}.webm`; + // eslint-disable-next-line max-len if (ThumbUtil.imageExtensions.includes(ext)) return ThumbUtil.generateThumbnailForImage(filename, output); + // eslint-disable-next-line max-len if (ThumbUtil.videoExtensions.includes(ext)) return ThumbUtil.generateThumbnailForVideo(filename, previewOutput); return null; } @@ -75,17 +77,21 @@ class ThumbUtil { } static getFileThumbnail(filename) { - // TODO: refactor so we don't do the same compare multiple times (poor cpu cycles) if (!filename) return null; const ext = path.extname(filename).toLowerCase(); - if (!ThumbUtil.imageExtensions.includes(ext) && !ThumbUtil.videoExtensions.includes(ext)) return null; - if (ThumbUtil.imageExtensions.includes(ext)) return { thumb: `${filename.slice(0, -ext.length)}.png` }; - if (ThumbUtil.videoExtensions.includes(ext)) { + + const isImage = ThumbUtil.imageExtensions.includes(ext); + const isVideo = ThumbUtil.videoExtensions.includes(ext); + + if (isImage) return { thumb: `${filename.slice(0, -ext.length)}.png` }; + if (isVideo) { return { thumb: `${filename.slice(0, -ext.length)}.png`, preview: `${filename.slice(0, -ext.length)}.webm`, }; } + + return null; } static async removeThumbs({ thumb, preview }) { diff --git a/src/api/utils/Util.js b/src/api/utils/Util.js index ab59c95..905948a 100644 --- a/src/api/utils/Util.js +++ b/src/api/utils/Util.js @@ -52,7 +52,7 @@ class Util { static getUniqueFilename(name) { const retry = (i = 0) => { - const filename = randomstring.generate({ + const filename = randomstring.generate({ length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10), capitalization: 'lowercase', }) + path.extname(name).toLowerCase(); @@ -81,7 +81,7 @@ class Util { /* It's funny but if you do i++ the asignment never gets done resulting in an infinite loop */ - if (i < 5) return retry(++i); + if (i < 5) return retry(i + 1); log.error('Couldnt allocate identifier for album'); return null; }; diff --git a/src/api/utils/videoPreview/FragmentPreview.js b/src/api/utils/videoPreview/FragmentPreview.js index 8815392..bf623c1 100644 --- a/src/api/utils/videoPreview/FragmentPreview.js +++ b/src/api/utils/videoPreview/FragmentPreview.js @@ -1,3 +1,4 @@ +/* eslint-disable no-bitwise */ const ffmpeg = require('fluent-ffmpeg'); const probe = require('ffmpeg-probe'); @@ -24,7 +25,7 @@ const getStartTime = (vDuration, fDuration, ignoreBeforePercent, ignoreAfterPerc return getRandomInt(ignoreBeforePercent * safeVDuration, ignoreAfterPercent * safeVDuration); }; -module.exports = async opts => { +module.exports = async (opts) => { const { log = noop, @@ -37,7 +38,7 @@ module.exports = async opts => { fragmentDurationSecond = 3, ignoreBeforePercent = 0.25, - ignoreAfterPercent = 0.75 + ignoreAfterPercent = 0.75, } = opts; const info = await probe(input); @@ -77,7 +78,7 @@ module.exports = async opts => { .outputOptions([`-t ${fragmentDurationSecond}`]) .noAudio() .output(output) - .on('start', cmd => log && log({ cmd })) + .on('start', (cmd) => log && log({ cmd })) .on('end', resolve) .on('error', reject) .run(); diff --git a/src/api/utils/videoPreview/FrameIntervalPreview.js b/src/api/utils/videoPreview/FrameIntervalPreview.js index 75f6d2b..8c5f1c3 100644 --- a/src/api/utils/videoPreview/FrameIntervalPreview.js +++ b/src/api/utils/videoPreview/FrameIntervalPreview.js @@ -1,9 +1,10 @@ +/* eslint-disable no-bitwise */ const ffmpeg = require('fluent-ffmpeg'); const probe = require('ffmpeg-probe'); const noop = () => {}; -module.exports = async opts => { +module.exports = async (opts) => { const { log = noop, @@ -15,13 +16,13 @@ module.exports = async opts => { output, numFrames, - numFramesPercent = 0.05 + numFramesPercent = 0.05, } = opts; const info = await probe(input); // const numFramesTotal = parseInt(info.streams[0].nb_frames, 10); const { avg_frame_rate: avgFrameRate, duration } = info.streams[0]; - const [frames, time] = avgFrameRate.split('/').map(e => parseInt(e, 10)); + const [frames, time] = avgFrameRate.split('/').map((e) => parseInt(e, 10)); const numFramesTotal = (frames / time) * duration; @@ -31,7 +32,7 @@ module.exports = async opts => { const result = { output, - numFrames: numFramesToCapture + numFrames: numFramesToCapture, }; await new Promise((resolve, reject) => { @@ -62,9 +63,9 @@ module.exports = async opts => { .noAudio() .outputFormat('webm') .output(output) - .on('start', cmd => log && log({ cmd })) + .on('start', (cmd) => log && log({ cmd })) .on('end', () => resolve()) - .on('error', err => reject(err)) + .on('error', (err) => reject(err)) .run(); }); diff --git a/src/site/components/album/AlbumDetails.vue b/src/site/components/album/AlbumDetails.vue index f117f2f..b411f13 100644 --- a/src/site/components/album/AlbumDetails.vue +++ b/src/site/components/album/AlbumDetails.vue @@ -6,34 +6,43 @@ :data="details.links || []" :mobile-cards="true">