aboutsummaryrefslogtreecommitdiff
path: root/src/api/routes
diff options
context:
space:
mode:
authorKana <[email protected]>2021-06-19 02:03:57 +0900
committerGitHub <[email protected]>2021-06-19 02:03:57 +0900
commit065c5221a0250838f1d1f9bb7a7922ff4f55e038 (patch)
tree8a69a81f00e6bff2752f4f7c59dcbbf21f893b20 /src/api/routes
parentchore: docs update (diff)
parentfix: potentially fix the blocked extensions array splitting (diff)
downloadhost.fuwn.me-065c5221a0250838f1d1f9bb7a7922ff4f55e038.tar.xz
host.fuwn.me-065c5221a0250838f1d1f9bb7a7922ff4f55e038.zip
Merge pull request #278 from Zephyrrus/Zephyrrus-feature/database_based_settings
Zephyrrus feature/database based settings
Diffstat (limited to 'src/api/routes')
-rw-r--r--src/api/routes/admin/fileGET.js2
-rw-r--r--src/api/routes/admin/userGET.js2
-rw-r--r--src/api/routes/albums/albumFullGET.js2
-rw-r--r--src/api/routes/albums/albumGET.js2
-rw-r--r--src/api/routes/albums/albumZipGET.js8
-rw-r--r--src/api/routes/albums/albumsGET.js2
-rw-r--r--src/api/routes/albums/link/linkPOST.js10
-rw-r--r--src/api/routes/auth/loginPOST.js3
-rw-r--r--src/api/routes/auth/registerPOST.js2
-rw-r--r--src/api/routes/files/fileGET.js2
-rw-r--r--src/api/routes/files/filesGET.js2
-rw-r--r--src/api/routes/search/searchGET.js2
-rw-r--r--src/api/routes/service/configAllGET.js17
-rw-r--r--src/api/routes/service/configGET.js21
-rw-r--r--src/api/routes/service/configPOST.js45
-rw-r--r--src/api/routes/service/configSchemaGET.js17
-rw-r--r--src/api/routes/uploads/uploadPOST.js12
17 files changed, 110 insertions, 41 deletions
diff --git a/src/api/routes/admin/fileGET.js b/src/api/routes/admin/fileGET.js
index 9605da4..72b96f1 100644
--- a/src/api/routes/admin/fileGET.js
+++ b/src/api/routes/admin/fileGET.js
@@ -15,7 +15,7 @@ class filesGET extends Route {
.select('id', 'username', 'enabled', 'createdAt', 'editedAt', 'apiKeyEditedAt', 'isAdmin')
.where({ id: file.userId })
.first();
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
// Additional relevant data
const filesFromUser = await db.table('files').where({ userId: user.id }).select('id');
diff --git a/src/api/routes/admin/userGET.js b/src/api/routes/admin/userGET.js
index 430dfd7..bf4f912 100644
--- a/src/api/routes/admin/userGET.js
+++ b/src/api/routes/admin/userGET.js
@@ -37,7 +37,7 @@ class usersGET extends Route {
}
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
return res.json({
diff --git a/src/api/routes/albums/albumFullGET.js b/src/api/routes/albums/albumFullGET.js
index d25fe15..32c7326 100644
--- a/src/api/routes/albums/albumFullGET.js
+++ b/src/api/routes/albums/albumFullGET.js
@@ -43,7 +43,7 @@ class albumGET extends Route {
// eslint-disable-next-line no-restricted-syntax
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
return res.json({
diff --git a/src/api/routes/albums/albumGET.js b/src/api/routes/albums/albumGET.js
index 4ac7089..e121a31 100644
--- a/src/api/routes/albums/albumGET.js
+++ b/src/api/routes/albums/albumGET.js
@@ -44,7 +44,7 @@ class albumGET extends Route {
}
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
// Add 1 more view to the link
diff --git a/src/api/routes/albums/albumZipGET.js b/src/api/routes/albums/albumZipGET.js
index 22b0b6f..8def099 100644
--- a/src/api/routes/albums/albumZipGET.js
+++ b/src/api/routes/albums/albumZipGET.js
@@ -38,13 +38,13 @@ class albumGET extends Route {
If the date when the album was zipped is greater than the album's last edit, we just send the zip to the user
*/
if (album.zippedAt > album.editedAt) {
- const filePath = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
+ const filePath = path.join(__dirname, '../../../../uploads', 'zips', `${album.userId}-${album.id}.zip`);
const exists = await jetpack.existsAsync(filePath);
/*
Make sure the file exists just in case, and if not, continue to it's generation.
*/
if (exists) {
- const fileName = `${process.env.SERVICE_NAME}-${identifier}.zip`;
+ const fileName = `${Util.config.serviceName}-${identifier}.zip`;
return res.download(filePath, fileName);
}
}
@@ -77,8 +77,8 @@ class albumGET extends Route {
.update('zippedAt', db.fn.now())
.wasMutated();
- const filePath = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
- const fileName = `${process.env.SERVICE_NAME}-${identifier}.zip`;
+ const filePath = path.join(__dirname, '../../../../uploads', 'zips', `${album.userId}-${album.id}.zip`);
+ const fileName = `${Util.config.serviceName}-${identifier}.zip`;
return res.download(filePath, fileName);
} catch (error) {
log.error(error);
diff --git a/src/api/routes/albums/albumsGET.js b/src/api/routes/albums/albumsGET.js
index 3c18d8f..98cc82e 100644
--- a/src/api/routes/albums/albumsGET.js
+++ b/src/api/routes/albums/albumsGET.js
@@ -37,7 +37,7 @@ class albumsGET extends Route {
// Fetch thumbnails and stuff
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
album.fileCount = fileCount[0].count;
diff --git a/src/api/routes/albums/link/linkPOST.js b/src/api/routes/albums/link/linkPOST.js
index 42eac58..7bc8051 100644
--- a/src/api/routes/albums/link/linkPOST.js
+++ b/src/api/routes/albums/link/linkPOST.js
@@ -20,16 +20,6 @@ class linkPOST extends Route {
.first();
if (!exists) return res.status(400).json({ message: 'Album doesn\t exist' });
- /*
- Count the amount of links created for that album already and error out if max was reached
- */
- const count = await db
- .table('links')
- .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' });
-
let { identifier } = req.body;
if (identifier) {
if (!user.isAdmin) return res.status(401).json({ message: 'Only administrators can create custom links' });
diff --git a/src/api/routes/auth/loginPOST.js b/src/api/routes/auth/loginPOST.js
index 373252b..cc72145 100644
--- a/src/api/routes/auth/loginPOST.js
+++ b/src/api/routes/auth/loginPOST.js
@@ -2,6 +2,7 @@ const bcrypt = require('bcrypt');
const moment = require('moment');
const JWT = require('jsonwebtoken');
const Route = require('../../structures/Route');
+const Util = require('../../utils/Util');
class loginPOST extends Route {
constructor() {
@@ -37,7 +38,7 @@ class loginPOST extends Route {
iss: 'chibisafe',
sub: user.id,
iat: moment.utc().valueOf()
- }, process.env.SECRET, { expiresIn: '30d' });
+ }, Util.config.secret, { expiresIn: '30d' });
return res.json({
message: 'Successfully logged in.',
diff --git a/src/api/routes/auth/registerPOST.js b/src/api/routes/auth/registerPOST.js
index 7b9eb3c..e740c83 100644
--- a/src/api/routes/auth/registerPOST.js
+++ b/src/api/routes/auth/registerPOST.js
@@ -12,7 +12,7 @@ class registerPOST extends Route {
async run(req, res, db) {
// Only allow admins to create new accounts if the sign up is deactivated
const user = await Util.isAuthorized(req);
- if ((!user || !user.isAdmin) && process.env.USER_ACCOUNTS === 'false') return res.status(401).json({ message: 'Creation of new accounts is currently disabled' });
+ if ((!user || !user.isAdmin) && !Util.config.userAccounts) 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;
diff --git a/src/api/routes/files/fileGET.js b/src/api/routes/files/fileGET.js
index 9ec6f22..2e6f0b8 100644
--- a/src/api/routes/files/fileGET.js
+++ b/src/api/routes/files/fileGET.js
@@ -16,7 +16,7 @@ class fileGET extends Route {
let file = await db.table('files').where({ id, userId: user.id }).first();
if (!file) return res.status(400).json({ message: 'The file doesn\'t exist or doesn\'t belong to the user' });
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
/*
Fetch the albums
diff --git a/src/api/routes/files/filesGET.js b/src/api/routes/files/filesGET.js
index 9e90633..20ccbc5 100644
--- a/src/api/routes/files/filesGET.js
+++ b/src/api/routes/files/filesGET.js
@@ -30,7 +30,7 @@ class filesGET extends Route {
// For each file, create the public link to be able to display the file
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
return res.json({
diff --git a/src/api/routes/search/searchGET.js b/src/api/routes/search/searchGET.js
index 187fcab..3cfcfef 100644
--- a/src/api/routes/search/searchGET.js
+++ b/src/api/routes/search/searchGET.js
@@ -53,7 +53,7 @@ class configGET extends Route {
// For each file, create the public link to be able to display the file
for (let file of files) {
- file = Util.constructFilePublicLink(file);
+ file = Util.constructFilePublicLink(req, file);
}
return res.json({
diff --git a/src/api/routes/service/configAllGET.js b/src/api/routes/service/configAllGET.js
new file mode 100644
index 0000000..fe9dae6
--- /dev/null
+++ b/src/api/routes/service/configAllGET.js
@@ -0,0 +1,17 @@
+const Route = require('../../structures/Route');
+const Util = require('../../utils/Util');
+
+class configGET extends Route {
+ constructor() {
+ super('/service/config/all', 'get', { adminOnly: true });
+ }
+
+ run(req, res) {
+ return res.json({
+ message: 'Successfully retrieved config',
+ config: Util.config
+ });
+ }
+}
+
+module.exports = configGET;
diff --git a/src/api/routes/service/configGET.js b/src/api/routes/service/configGET.js
index bc91a7e..c8d88d3 100644
--- a/src/api/routes/service/configGET.js
+++ b/src/api/routes/service/configGET.js
@@ -1,24 +1,23 @@
const Route = require('../../structures/Route');
+const Util = require('../../utils/Util');
class configGET extends Route {
constructor() {
- super('/service/config', 'get', { adminOnly: true });
+ super('/service/config', 'get', { bypassAuth: true });
}
run(req, res) {
return res.json({
message: 'Successfully retrieved config',
config: {
- serviceName: process.env.SERVICE_NAME,
- uploadFolder: process.env.UPLOAD_FOLDER,
- linksPerAlbum: parseInt(process.env.MAX_LINKS_PER_ALBUM, 10),
- 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',
- generateZips: process.env.GENERATE_ZIPS === 'true',
- publicMode: process.env.PUBLIC_MODE === 'true',
- enableAccounts: process.env.USER_ACCOUNTS === 'true'
+ version: process.env.npm_package_version,
+ serviceName: Util.config.serviceName,
+ maxUploadSize: Util.config.maxSize,
+ filenameLength: Util.config.generatedFilenameLength,
+ albumLinkLength: Util.config.generatedAlbumLength,
+ chunkSize: Util.config.chunkSize,
+ publicMode: Util.config.publicMode,
+ userAccounts: Util.config.userAccounts
}
});
}
diff --git a/src/api/routes/service/configPOST.js b/src/api/routes/service/configPOST.js
new file mode 100644
index 0000000..68af467
--- /dev/null
+++ b/src/api/routes/service/configPOST.js
@@ -0,0 +1,45 @@
+const Route = require('../../structures/Route');
+const Util = require('../../utils/Util');
+
+const { schema } = require('../../structures/Setting');
+
+const joiOptions = {
+ abortEarly: false, // include all errors
+ allowUnknown: true, // ignore unknown props
+ stripUnknown: true // remove unknown props
+};
+
+class configGET extends Route {
+ constructor() {
+ super('/service/config', 'post', { adminOnly: true });
+ }
+
+ async run(req, res) {
+ const { settings } = req.body;
+ const { error, value } = schema.validate(settings, joiOptions);
+ if (error) {
+ return res.status(400).json({
+ errors: error.details.reduce((acc, v) => {
+ for (const p of v.path) {
+ acc[p] = (acc[p] || []).concat(v.message);
+ }
+ return acc;
+ }, {})
+ });
+ }
+
+ await Util.wipeConfigDb();
+
+ const keys = Object.keys(value);
+ for await (const item of keys) {
+ Util.writeConfigToDb({
+ key: item,
+ value: value[item]
+ });
+ }
+
+ return res.status(200).json({ value });
+ }
+}
+
+module.exports = configGET;
diff --git a/src/api/routes/service/configSchemaGET.js b/src/api/routes/service/configSchemaGET.js
new file mode 100644
index 0000000..90befa9
--- /dev/null
+++ b/src/api/routes/service/configSchemaGET.js
@@ -0,0 +1,17 @@
+const Route = require('../../structures/Route');
+const { configSchema } = require('../../structures/Setting');
+
+class configGET extends Route {
+ constructor() {
+ super('/service/config/schema', 'get', { adminOnly: true });
+ }
+
+ run(req, res) {
+ return res.json({
+ message: 'Successfully retrieved schema',
+ schema: configSchema
+ });
+ }
+}
+
+module.exports = configGET;
diff --git a/src/api/routes/uploads/uploadPOST.js b/src/api/routes/uploads/uploadPOST.js
index a0dba27..4e96c80 100644
--- a/src/api/routes/uploads/uploadPOST.js
+++ b/src/api/routes/uploads/uploadPOST.js
@@ -8,8 +8,8 @@ const multerStorage = require('../../utils/multerStorage');
const chunksData = {};
const chunkedUploadsTimeout = 1800000;
-const chunksDir = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'chunks');
-const uploadDir = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER);
+const chunksDir = path.join(__dirname, '../../../../uploads/chunks');
+const uploadDir = path.join(__dirname, '../../../../uploads');
const cleanUpChunks = async (uuid, onTimeout) => {
@@ -72,7 +72,7 @@ const initChunks = async uuid => {
const executeMulter = multer({
// Guide: https://github.com/expressjs/multer#limits
limits: {
- fileSize: parseInt(process.env.MAX_SIZE, 10) * (1000 * 1000),
+ fileSize: Util.config.maxSize * (1000 * 1000),
// Maximum number of non-file fields.
// Dropzone.js will add 6 extra fields for chunked uploads.
// We don't use them for anything else.
@@ -257,7 +257,7 @@ class uploadPOST extends Route {
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 && !Util.config.publicMode) return res.status(401).json({ message: 'Not authorized to use this resource' });
const { finishedchunks } = req.headers;
const albumId = req.headers.albumid ? req.headers.albumid === 'null' ? null : req.headers.albumid : null;
if (albumId && !user) return res.status(401).json({ message: 'Only registered users can upload files to an album' });
@@ -282,8 +282,8 @@ class uploadPOST extends Route {
if (albumId) await Util.saveFileToAlbum(db, albumId, result.id);
- result.file = Util.constructFilePublicLink(result.file);
- result.deleteUrl = `${process.env.DOMAIN}/api/file/${result.id[0]}`;
+ result.file = Util.constructFilePublicLink(req, result.file);
+ result.deleteUrl = `${Util.getHost(req)}/api/file/${result.id[0]}`;
return res.status(201).send({
message: 'Sucessfully uploaded the file.',