diff options
| author | Pitu <[email protected]> | 2019-10-13 02:53:45 +0900 |
|---|---|---|
| committer | Pitu <[email protected]> | 2019-10-13 02:53:45 +0900 |
| commit | cba7bf8586f59a049f79aba586db201ac6f3530b (patch) | |
| tree | 46aeabe2b5463456ef3eb241a38407a5699e3728 /src/api | |
| parent | don't log out on API error (diff) | |
| download | host.fuwn.me-cba7bf8586f59a049f79aba586db201ac6f3530b.tar.xz host.fuwn.me-cba7bf8586f59a049f79aba586db201ac6f3530b.zip | |
This commit adds a bunch of features for admins:
* banning IP
* see files from other users if you are admin
* be able to see details of an uploaded file and it's user
* improved display of thumbnails for non-image files
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/database/migrations/20190221225812_initialMigration.js | 24 | ||||
| -rw-r--r-- | src/api/database/migrations/20190221225813_addTags.js | 21 | ||||
| -rw-r--r-- | src/api/routes/admin/banIP.js | 25 | ||||
| -rw-r--r-- | src/api/routes/admin/unBanIP.js | 27 | ||||
| -rw-r--r-- | src/api/routes/admin/userGET.js | 32 | ||||
| -rw-r--r-- | src/api/routes/files/fileGET.js | 29 | ||||
| -rw-r--r-- | src/api/structures/Route.js | 5 |
7 files changed, 141 insertions, 22 deletions
diff --git a/src/api/database/migrations/20190221225812_initialMigration.js b/src/api/database/migrations/20190221225812_initialMigration.js index a9ce2c7..84bda7e 100644 --- a/src/api/database/migrations/20190221225812_initialMigration.js +++ b/src/api/database/migrations/20190221225812_initialMigration.js @@ -62,6 +62,27 @@ exports.up = async knex => { table.integer('albumId'); table.integer('linkId'); }); + + await knex.schema.createTable('tags', table => { + table.increments(); + table.string('uuid'); + table.integer('userId'); + table.string('name'); + table.timestamp('createdAt'); + table.timestamp('editedAt'); + }); + + await knex.schema.createTable('fileTags', table => { + table.increments(); + table.integer('fileId'); + table.integer('tagId'); + }); + + await knex.schema.createTable('bans', table => { + table.increments(); + table.string('ip'); + table.timestamp('createdAt'); + }); }; exports.down = async knex => { await knex.schema.dropTableIfExists('users'); @@ -70,4 +91,7 @@ exports.down = async knex => { await knex.schema.dropTableIfExists('links'); await knex.schema.dropTableIfExists('albumsFiles'); await knex.schema.dropTableIfExists('albumsLinks'); + await knex.schema.dropTableIfExists('tags'); + await knex.schema.dropTableIfExists('fileTags'); + await knex.schema.dropTableIfExists('bans'); }; diff --git a/src/api/database/migrations/20190221225813_addTags.js b/src/api/database/migrations/20190221225813_addTags.js deleted file mode 100644 index ef71877..0000000 --- a/src/api/database/migrations/20190221225813_addTags.js +++ /dev/null @@ -1,21 +0,0 @@ -exports.up = async knex => { - await knex.schema.createTable('tags', table => { - table.increments(); - table.string('uuid'); - table.integer('userId'); - table.string('name'); - table.timestamp('createdAt'); - table.timestamp('editedAt'); - }); - - await knex.schema.createTable('fileTags', table => { - table.increments(); - table.integer('fileId'); - table.integer('tagId'); - }); -}; - -exports.down = async knex => { - await knex.schema.dropTableIfExists('tags'); - await knex.schema.dropTableIfExists('fileTags'); -}; diff --git a/src/api/routes/admin/banIP.js b/src/api/routes/admin/banIP.js new file mode 100644 index 0000000..692880d --- /dev/null +++ b/src/api/routes/admin/banIP.js @@ -0,0 +1,25 @@ +const Route = require('../../structures/Route'); + +class banIP extends Route { + constructor() { + super('/admin/ban/ip', 'post', { adminOnly: true }); + } + + async run(req, res, db) { + if (!req.body) return res.status(400).json({ message: 'No body provided' }); + const { ip } = req.body; + if (!ip) return res.status(400).json({ message: 'No ip provided' }); + + try { + await db.table('bans').insert({ ip }); + } catch (error) { + return super.error(res, error); + } + + return res.json({ + message: 'Successfully banned the ip' + }); + } +} + +module.exports = banIP; diff --git a/src/api/routes/admin/unBanIP.js b/src/api/routes/admin/unBanIP.js new file mode 100644 index 0000000..493834b --- /dev/null +++ b/src/api/routes/admin/unBanIP.js @@ -0,0 +1,27 @@ +const Route = require('../../structures/Route'); + +class unBanIP extends Route { + constructor() { + super('/admin/unban/ip', 'post', { adminOnly: true }); + } + + async run(req, res, db) { + if (!req.body) return res.status(400).json({ message: 'No body provided' }); + const { ip } = req.body; + if (!ip) return res.status(400).json({ message: 'No ip provided' }); + + try { + await db.table('bans') + .where({ ip }) + .delete(); + } catch (error) { + return super.error(res, error); + } + + return res.json({ + message: 'Successfully unbanned the ip' + }); + } +} + +module.exports = unBanIP; diff --git a/src/api/routes/admin/userGET.js b/src/api/routes/admin/userGET.js new file mode 100644 index 0000000..895a565 --- /dev/null +++ b/src/api/routes/admin/userGET.js @@ -0,0 +1,32 @@ +const Route = require('../../structures/Route'); +const Util = require('../../utils/Util'); + +class usersGET extends Route { + constructor() { + super('/admin/users/:id', 'get', { adminOnly: true }); + } + + async run(req, res, db) { + const { id } = req.params; + if (!id) return res.status(400).json({ message: 'Invalid user ID supplied' }); + + try { + const user = await db.table('users').where({ id }).first(); + const files = await db.table('files').where({ userId: user.id }); + + for (let file of files) { + file = Util.constructFilePublicLink(file); + } + + return res.json({ + message: 'Successfully retrieved user', + user, + files + }); + } catch (error) { + return super.error(res, error); + } + } +} + +module.exports = usersGET; diff --git a/src/api/routes/files/fileGET.js b/src/api/routes/files/fileGET.js new file mode 100644 index 0000000..3bb8da4 --- /dev/null +++ b/src/api/routes/files/fileGET.js @@ -0,0 +1,29 @@ +const Route = require('../../structures/Route'); +const Util = require('../../utils/Util'); + +class filesGET extends Route { + constructor() { + super('/file/:id', 'get', { adminOnly: true }); + } + + async run(req, res, db) { + const { id } = req.params; + if (!id) return res.status(400).json({ message: 'Invalid file ID supplied' }); + + let file = await db.table('files').where({ id }).first(); + const user = await db.table('users').where({ id: file.userId }).first(); + file = Util.constructFilePublicLink(file); + + // Additional relevant data + const filesFromUser = await db.table('files').where({ userId: user.id }).select('id'); + user.fileCount = filesFromUser.length; + + return res.json({ + message: 'Successfully retrieved file', + file, + user + }); + } +} + +module.exports = filesGET; diff --git a/src/api/structures/Route.js b/src/api/structures/Route.js index c04c585..2db9bc6 100644 --- a/src/api/structures/Route.js +++ b/src/api/structures/Route.js @@ -52,7 +52,10 @@ class Route { this.options = options || {}; } - authorize(req, res) { + async authorize(req, res) { + const banned = await db.table('bans').where({ ip: req.ip }).first(); + 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); if (req.headers.apiKey) return this.authorizeApiKey(req, res, req.headers.apiKey); if (!req.headers.authorization) return res.status(401).json({ message: 'No authorization header provided' }); |