aboutsummaryrefslogtreecommitdiff
path: root/src/api/utils/Util.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/utils/Util.js')
-rw-r--r--src/api/utils/Util.js115
1 files changed, 89 insertions, 26 deletions
diff --git a/src/api/utils/Util.js b/src/api/utils/Util.js
index 6feedd4..73b2b98 100644
--- a/src/api/utils/Util.js
+++ b/src/api/utils/Util.js
@@ -12,37 +12,102 @@ const log = require('./Log');
const ThumbUtil = require('./ThumbUtil');
const StatsGenerator = require('./StatsGenerator');
-const blockedExtensions = process.env.BLOCKED_EXTENSIONS.split(',');
const preserveExtensions = ['.tar.gz', '.tar.z', '.tar.bz2', '.tar.lzma', '.tar.lzo', '.tar.xz'];
-let statsLastSavedTime = null;
-
class Util {
- static uploadPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER);
+ static uploadPath = path.join(__dirname, '../../../', 'uploads');
+ static statsLastSavedTime = null;
+ static _config = null;
+
+ static get config() {
+ if (this._config) return this._config;
+ return (async () => {
+ if (this._config === null) {
+ const conf = await db('settings').select('key', 'value');
+ this._config = conf.reduce((obj, item) => (
+ // eslint-disable-next-line no-sequences
+ obj[item.key] = typeof item.value === 'string' || item.value instanceof String ? JSON.parse(item.value) : item.value, obj
+ ), {});
+ }
+ return this._config;
+ })();
+ }
+
+ static invalidateConfigCache() {
+ this._config = null;
+ }
+
+ static getEnvironmentDefaults() {
+ return {
+ domain: process.env.DOMAIN,
+ routePrefix: process.env.ROUTE_PREFIX || '/api',
+ rateLimitWindow: process.env.RATE_LIMIT_WINDOW || 2,
+ rateLimitMax: process.env.RATE_LIMIT_MAX || 5,
+ secret: process.env.SECRET || randomstring.generate(64),
+ serviceName: process.env.SERVICE_NAME || 'change-me',
+ chunkSize: process.env.CHUNK_SIZE || 90,
+ maxSize: process.env.MAX_SIZE || 5000,
+ // eslint-disable-next-line eqeqeq
+ generateZips: process.env.GENERATE_ZIPS == undefined ? true : false,
+ generatedFilenameLength: process.env.GENERATED_FILENAME_LENGTH || 12,
+ generatedAlbumLength: process.env.GENERATED_ALBUM_LENGTH || 6,
+ blockedExtensions: process.env.BLOCKED_EXTENSIONS ? process.env.BLOCKED_EXTENSIONS.split(',') : ['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'],
+ // eslint-disable-next-line eqeqeq
+ publicMode: process.env.PUBLIC_MODE == undefined ? true : false,
+ // eslint-disable-next-line eqeqeq
+ userAccounts: process.env.USER_ACCOUNTS == undefined ? true : false,
+ metaThemeColor: process.env.META_THEME_COLOR || '#20222b',
+ metaDescription: process.env.META_DESCRIPTION || 'Blazing fast file uploader and bunker written in node! 🚀',
+ metaKeywords: process.env.META_KEYWORDS || 'chibisafe,lolisafe,upload,uploader,file,vue,images,ssr,file uploader,free',
+ metaTwitterHandle: process.env.META_TWITTER_HANDLE || '@your-handle'
+ };
+ }
+
+ static async wipeConfigDb() {
+ try {
+ await db.table('settings').del();
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ static async writeConfigToDb(config, wipe = false) {
+ // TODO: Check that the config passes the joi schema validation
+ if (!config || !config.key) return;
+ try {
+ config.value = JSON.stringify(config.value);
+ await db.table('settings').insert(config);
+ } catch (error) {
+ console.error(error);
+ } finally {
+ this.invalidateConfigCache();
+ }
+ }
static uuid() {
return uuidv4();
}
static isExtensionBlocked(extension) {
- return blockedExtensions.includes(extension);
+ return this.config.blockedExtensions.includes(extension);
}
static getMimeFromType(fileTypeMimeObj) {
return fileTypeMimeObj ? fileTypeMimeObj.mime : undefined;
}
- static constructFilePublicLink(file) {
+ static constructFilePublicLink(req, file) {
/*
TODO: This wont work without a reverse proxy serving both
the site and the API under the same domain. Pls fix.
*/
- file.url = `${process.env.DOMAIN}/${file.name}`;
+ const host = this.getHost(req);
+ file.url = `${host}/${file.name}`;
const { thumb, preview } = ThumbUtil.getFileThumbnail(file.name) || {};
if (thumb) {
- file.thumb = `${process.env.DOMAIN}/thumbs/${thumb}`;
- file.thumbSquare = `${process.env.DOMAIN}/thumbs/square/${thumb}`;
- file.preview = preview && `${process.env.DOMAIN}/thumbs/preview/${preview}`;
+ file.thumb = `${host}/thumbs/${thumb}`;
+ file.thumbSquare = `${host}/thumbs/square/${thumb}`;
+ file.preview = preview && `${host}/thumbs/preview/${preview}`;
}
return file;
}
@@ -50,7 +115,7 @@ class Util {
static getUniqueFilename(extension) {
const retry = (i = 0) => {
const filename = randomstring.generate({
- length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
+ length: this.config.generatedFilenameLength,
capitalization: 'lowercase'
}) + extension;
@@ -67,7 +132,7 @@ class Util {
static getUniqueAlbumIdentifier() {
const retry = async (i = 0) => {
const identifier = randomstring.generate({
- length: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10),
+ length: this.config.generatedAlbumLength,
capitalization: 'lowercase'
});
const exists = await db
@@ -164,7 +229,7 @@ class Util {
const token = req.headers.authorization.split(' ')[1];
if (!token) return false;
- return JWT.verify(token, process.env.SECRET, async (error, decoded) => {
+ return JWT.verify(token, this.config.secret, async (error, decoded) => {
if (error) {
log.error(error);
return false;
@@ -190,13 +255,7 @@ class Util {
zip.addLocalFile(path.join(Util.uploadPath, file));
}
zip.writeZip(
- path.join(
- __dirname,
- '../../../',
- process.env.UPLOAD_FOLDER,
- 'zips',
- `${album.userId}-${album.id}.zip`
- )
+ path.join(__dirname, '../../../', 'uploads', 'zips', `${album.userId}-${album.id}.zip`)
);
} catch (error) {
log.error(error);
@@ -205,8 +264,8 @@ class Util {
static generateThumbnails = ThumbUtil.generateThumbnails;
- static async fileExists(res, exists, filename) {
- exists = Util.constructFilePublicLink(exists);
+ static async fileExists(req, res, exists, filename) {
+ exists = Util.constructFilePublicLink(req, exists);
res.json({
message: 'Successfully uploaded the file.',
name: exists.name,
@@ -214,7 +273,7 @@ class Util {
size: exists.size,
url: exists.url,
thumb: exists.thumb,
- deleteUrl: `${process.env.DOMAIN}/api/file/${exists.id}`,
+ deleteUrl: `${this.getHost(req)}/api/file/${exists.id}`,
repeated: true
});
@@ -238,7 +297,7 @@ class Util {
.first();
if (dbFile) {
- await this.fileExists(res, dbFile, file.data.filename);
+ await this.fileExists(req, res, dbFile, file.data.filename);
return;
}
@@ -320,7 +379,7 @@ class Util {
// skip generating and saving new stats.
if (!force &&
(!db.userParams.lastMutationTime ||
- (statsLastSavedTime && statsLastSavedTime > db.userParams.lastMutationTime)
+ (Util.statsLastSavedTime && Util.statsLastSavedTime > db.userParams.lastMutationTime)
)
) {
return;
@@ -341,11 +400,15 @@ class Util {
await db.table('statistics').insert({ type, data: JSON.stringify(data), createdAt: now, batchId });
}
- statsLastSavedTime = now.getTime();
+ Util.statsLastSavedTime = now.getTime();
} catch (error) {
console.error(error);
}
}
+
+ static getHost(req) {
+ return `${req.protocol}://${req.headers.host}`;
+ }
}
module.exports = Util;