chore: update process.env usage
This commit is contained in:
parent
9b28e56e09
commit
d3c80127ec
|
@ -10,16 +10,12 @@ const clientConfig = {
|
||||||
serviceName: process.env.SERVICE_NAME,
|
serviceName: process.env.SERVICE_NAME,
|
||||||
maxFileSize: parseInt(process.env.MAX_SIZE, 10),
|
maxFileSize: parseInt(process.env.MAX_SIZE, 10),
|
||||||
chunkSize: parseInt(process.env.CHUNK_SIZE, 10),
|
chunkSize: parseInt(process.env.CHUNK_SIZE, 10),
|
||||||
maxLinksPerAlbum: parseInt(process.env.MAX_LINKS_PER_ALBUM, 10),
|
|
||||||
publicMode: process.env.PUBLIC_MODE === 'true',
|
publicMode: process.env.PUBLIC_MODE === 'true',
|
||||||
userAccounts: process.env.USER_ACCOUNTS === 'true'
|
userAccounts: process.env.USER_ACCOUNTS === 'true'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ssr: true,
|
ssr: true,
|
||||||
server: {
|
|
||||||
port: process.env.WEBSITE_PORT
|
|
||||||
},
|
|
||||||
srcDir: 'src/site/',
|
srcDir: 'src/site/',
|
||||||
head: {
|
head: {
|
||||||
title: process.env.SERVICE_NAME,
|
title: process.env.SERVICE_NAME,
|
||||||
|
|
|
@ -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 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) {
|
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);
|
const exists = await jetpack.existsAsync(filePath);
|
||||||
/*
|
/*
|
||||||
Make sure the file exists just in case, and if not, continue to it's generation.
|
Make sure the file exists just in case, and if not, continue to it's generation.
|
||||||
*/
|
*/
|
||||||
if (exists) {
|
if (exists) {
|
||||||
const fileName = `${process.env.SERVICE_NAME}-${identifier}.zip`;
|
const fileName = `${Util.config.serviceName}-${identifier}.zip`;
|
||||||
return res.download(filePath, fileName);
|
return res.download(filePath, fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,8 @@ class albumGET extends Route {
|
||||||
.update('zippedAt', db.fn.now())
|
.update('zippedAt', db.fn.now())
|
||||||
.wasMutated();
|
.wasMutated();
|
||||||
|
|
||||||
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 fileName = `${process.env.SERVICE_NAME}-${identifier}.zip`;
|
const fileName = `${Util.config.serviceName}-${identifier}.zip`;
|
||||||
return res.download(filePath, fileName);
|
return res.download(filePath, fileName);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
|
|
|
@ -2,6 +2,7 @@ const bcrypt = require('bcrypt');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const JWT = require('jsonwebtoken');
|
const JWT = require('jsonwebtoken');
|
||||||
const Route = require('../../structures/Route');
|
const Route = require('../../structures/Route');
|
||||||
|
const Util = require('../../utils/Util');
|
||||||
|
|
||||||
class loginPOST extends Route {
|
class loginPOST extends Route {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -37,7 +38,7 @@ class loginPOST extends Route {
|
||||||
iss: 'chibisafe',
|
iss: 'chibisafe',
|
||||||
sub: user.id,
|
sub: user.id,
|
||||||
iat: moment.utc().valueOf()
|
iat: moment.utc().valueOf()
|
||||||
}, process.env.SECRET, { expiresIn: '30d' });
|
}, Util.config.secret, { expiresIn: '30d' });
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
message: 'Successfully logged in.',
|
message: 'Successfully logged in.',
|
||||||
|
|
|
@ -12,7 +12,7 @@ class registerPOST extends Route {
|
||||||
async run(req, res, db) {
|
async run(req, res, db) {
|
||||||
// Only allow admins to create new accounts if the sign up is deactivated
|
// Only allow admins to create new accounts if the sign up is deactivated
|
||||||
const user = await Util.isAuthorized(req);
|
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' });
|
if (!req.body) return res.status(400).json({ message: 'No body provided' });
|
||||||
const { username, password } = req.body;
|
const { username, password } = req.body;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const Route = require('../../structures/Route');
|
const Route = require('../../structures/Route');
|
||||||
|
const Util = require('../../utils/Util');
|
||||||
|
|
||||||
class configGET extends Route {
|
class configGET extends Route {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -9,15 +10,13 @@ class configGET extends Route {
|
||||||
return res.json({
|
return res.json({
|
||||||
message: 'Successfully retrieved config',
|
message: 'Successfully retrieved config',
|
||||||
config: {
|
config: {
|
||||||
serviceName: process.env.SERVICE_NAME,
|
serviceName: Util.config.serviceName,
|
||||||
uploadFolder: process.env.UPLOAD_FOLDER,
|
maxUploadSize: Util.config.maxSize,
|
||||||
maxUploadSize: parseInt(process.env.MAX_SIZE, 10),
|
filenameLength: Util.config.generatedFilenameLength,
|
||||||
filenameLength: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
|
albumLinkLength: Util.config.generatedAlbumLength,
|
||||||
albumLinkLength: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10),
|
generateZips: Util.config.generateZips,
|
||||||
generateThumbnails: process.env.GENERATE_THUMBNAILS === 'true',
|
publicMode: Util.config.publicMode,
|
||||||
generateZips: process.env.GENERATE_ZIPS === 'true',
|
enableAccounts: Util.config.userAccounts
|
||||||
publicMode: process.env.PUBLIC_MODE === 'true',
|
|
||||||
enableAccounts: process.env.USER_ACCOUNTS === 'true'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ const multerStorage = require('../../utils/multerStorage');
|
||||||
|
|
||||||
const chunksData = {};
|
const chunksData = {};
|
||||||
const chunkedUploadsTimeout = 1800000;
|
const chunkedUploadsTimeout = 1800000;
|
||||||
const chunksDir = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'chunks');
|
const chunksDir = path.join(__dirname, '../../../../uploads/chunks');
|
||||||
const uploadDir = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER);
|
const uploadDir = path.join(__dirname, '../../../../uploads');
|
||||||
|
|
||||||
|
|
||||||
const cleanUpChunks = async (uuid, onTimeout) => {
|
const cleanUpChunks = async (uuid, onTimeout) => {
|
||||||
|
@ -72,7 +72,7 @@ const initChunks = async uuid => {
|
||||||
const executeMulter = multer({
|
const executeMulter = multer({
|
||||||
// Guide: https://github.com/expressjs/multer#limits
|
// Guide: https://github.com/expressjs/multer#limits
|
||||||
limits: {
|
limits: {
|
||||||
fileSize: parseInt(process.env.MAX_SIZE, 10) * (1000 * 1000),
|
fileSize: Util.config.maxSize * (1000 * 1000),
|
||||||
// Maximum number of non-file fields.
|
// Maximum number of non-file fields.
|
||||||
// Dropzone.js will add 6 extra fields for chunked uploads.
|
// Dropzone.js will add 6 extra fields for chunked uploads.
|
||||||
// We don't use them for anything else.
|
// We don't use them for anything else.
|
||||||
|
@ -257,7 +257,7 @@ class uploadPOST extends Route {
|
||||||
|
|
||||||
async run(req, res, db) {
|
async run(req, res, db) {
|
||||||
const user = await Util.isAuthorized(req);
|
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 { finishedchunks } = req.headers;
|
||||||
const albumId = req.headers.albumid ? req.headers.albumid === 'null' ? null : req.headers.albumid : null;
|
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' });
|
if (albumId && !user) return res.status(401).json({ message: 'Only registered users can upload files to an album' });
|
||||||
|
|
|
@ -2,6 +2,7 @@ const JWT = require('jsonwebtoken');
|
||||||
const db = require('./Database');
|
const db = require('./Database');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const log = require('../utils/Log');
|
const log = require('../utils/Log');
|
||||||
|
const Util = require('../utils/Util');
|
||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
constructor(path, method, options) {
|
constructor(path, method, options) {
|
||||||
|
@ -30,7 +31,7 @@ class Route {
|
||||||
const token = req.headers.authorization.split(' ')[1];
|
const token = req.headers.authorization.split(' ')[1];
|
||||||
if (!token) return res.status(401).json({ message: 'No authorization header provided' });
|
if (!token) return res.status(401).json({ message: 'No authorization header provided' });
|
||||||
|
|
||||||
return JWT.verify(token, process.env.SECRET, async (error, decoded) => {
|
return JWT.verify(token, Util.config.secret, async (error, decoded) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
return res.status(401).json({ message: 'Invalid token' });
|
return res.status(401).json({ message: 'Invalid token' });
|
||||||
|
|
|
@ -19,11 +19,10 @@ const CronJob = require('cron').CronJob;
|
||||||
const log = require('../utils/Log');
|
const log = require('../utils/Log');
|
||||||
|
|
||||||
const Util = require('../utils/Util');
|
const Util = require('../utils/Util');
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const rateLimiter = new RateLimit({
|
const rateLimiter = new RateLimit({
|
||||||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW, 10),
|
windowMs: parseInt(Util.config.rateLimitWindow, 10),
|
||||||
max: parseInt(process.env.RATE_LIMIT_MAX, 10),
|
max: parseInt(Util.config.rateLimitMax, 10),
|
||||||
delayMs: 0
|
delayMs: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,6 +64,7 @@ class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerAllTheRoutes() {
|
registerAllTheRoutes() {
|
||||||
|
console.log(Util.config);
|
||||||
jetpack.find(this.routesFolder, { matching: '*.js' }).forEach(routeFile => {
|
jetpack.find(this.routesFolder, { matching: '*.js' }).forEach(routeFile => {
|
||||||
const RouteClass = require(path.join('../../../', routeFile));
|
const RouteClass = require(path.join('../../../', routeFile));
|
||||||
let routes = [RouteClass];
|
let routes = [RouteClass];
|
||||||
|
@ -72,8 +72,8 @@ class Server {
|
||||||
for (const File of routes) {
|
for (const File of routes) {
|
||||||
try {
|
try {
|
||||||
const route = new File();
|
const route = new File();
|
||||||
this.server[route.method](process.env.ROUTE_PREFIX + route.path, route.authorize.bind(route));
|
this.server[route.method](Util.config.routePrefix + route.path, route.authorize.bind(route));
|
||||||
log.info(`Found route ${route.method.toUpperCase()} ${process.env.ROUTE_PREFIX}${route.path}`);
|
log.info(`Found route ${route.method.toUpperCase()} ${Util.config.routePrefix}${route.path}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(`Failed loading route from file ${routeFile} with error: ${e.message}`);
|
log.error(`Failed loading route from file ${routeFile} with error: ${e.message}`);
|
||||||
}
|
}
|
||||||
|
@ -110,4 +110,11 @@ class Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new Server().start();
|
const start = async () => {
|
||||||
|
const conf = await Util.config;
|
||||||
|
console.log(conf);
|
||||||
|
new Server().start();
|
||||||
|
};
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,12 @@ class ThumbUtil {
|
||||||
static imageExtensions = ['.jpg', '.jpeg', '.gif', '.png', '.webp'];
|
static imageExtensions = ['.jpg', '.jpeg', '.gif', '.png', '.webp'];
|
||||||
static videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
|
static videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
|
||||||
|
|
||||||
static thumbPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs');
|
static thumbPath = path.join(__dirname, '../../../', 'uploads', 'thumbs');
|
||||||
static squareThumbPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs', 'square');
|
static squareThumbPath = path.join(__dirname, '../../../', 'uploads', 'thumbs', 'square');
|
||||||
static videoPreviewPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs', 'preview');
|
static videoPreviewPath = path.join(__dirname, '../../../', 'uploads', 'thumbs', 'preview');
|
||||||
|
|
||||||
static generateThumbnails(filename) {
|
static generateThumbnails(filename) {
|
||||||
|
if (!filename) return;
|
||||||
const ext = path.extname(filename).toLowerCase();
|
const ext = path.extname(filename).toLowerCase();
|
||||||
const output = `${filename.slice(0, -ext.length)}.webp`;
|
const output = `${filename.slice(0, -ext.length)}.webp`;
|
||||||
const previewOutput = `${filename.slice(0, -ext.length)}.webm`;
|
const previewOutput = `${filename.slice(0, -ext.length)}.webm`;
|
||||||
|
@ -27,7 +28,7 @@ class ThumbUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static async generateThumbnailForImage(filename, output) {
|
static async generateThumbnailForImage(filename, output) {
|
||||||
const filePath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, filename);
|
const filePath = path.join(__dirname, '../../../', 'uploads', filename);
|
||||||
|
|
||||||
const file = await jetpack.readAsync(filePath, 'buffer');
|
const file = await jetpack.readAsync(filePath, 'buffer');
|
||||||
await sharp(file)
|
await sharp(file)
|
||||||
|
@ -41,7 +42,7 @@ class ThumbUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static async generateThumbnailForVideo(filename, output) {
|
static async generateThumbnailForVideo(filename, output) {
|
||||||
const filePath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, filename);
|
const filePath = path.join(__dirname, '../../../', 'uploads', filename);
|
||||||
|
|
||||||
ffmpeg(filePath)
|
ffmpeg(filePath)
|
||||||
.thumbnail({
|
.thumbnail({
|
||||||
|
|
|
@ -12,25 +12,22 @@ const log = require('./Log');
|
||||||
const ThumbUtil = require('./ThumbUtil');
|
const ThumbUtil = require('./ThumbUtil');
|
||||||
const StatsGenerator = require('./StatsGenerator');
|
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'];
|
const preserveExtensions = ['.tar.gz', '.tar.z', '.tar.bz2', '.tar.lzma', '.tar.lzo', '.tar.xz'];
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
static uploadPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER);
|
static uploadPath = path.join(__dirname, '../../../', 'uploads');
|
||||||
static statsLastSavedTime = null;
|
static statsLastSavedTime = null;
|
||||||
static _config = null;
|
static _config = null;
|
||||||
|
|
||||||
static get config() {
|
static get config() {
|
||||||
|
if (this._config) return this._config;
|
||||||
return (async () => {
|
return (async () => {
|
||||||
if (this._config === null) {
|
if (this._config === null) {
|
||||||
const conf = await db('config').select('key', 'value');
|
const conf = await db('settings').select('key', 'value');
|
||||||
this._config = conf.reduce((acc, { key, value }) => {
|
this._config = conf.reduce((obj, item) => (
|
||||||
if (typeof value === 'string' || value instanceof String) {
|
// eslint-disable-next-line no-sequences
|
||||||
acc[key] = JSON.parse(value);
|
obj[item.key] = typeof item.value === 'string' || item.value instanceof String ? JSON.parse(item.value) : item.value, obj
|
||||||
} else {
|
), {});
|
||||||
acc[key] = value;
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
}
|
}
|
||||||
return this._config;
|
return this._config;
|
||||||
})();
|
})();
|
||||||
|
@ -49,15 +46,15 @@ class Util {
|
||||||
serviceName: process.env.SERVICE_NAME || 'change-me',
|
serviceName: process.env.SERVICE_NAME || 'change-me',
|
||||||
chunkSize: process.env.CHUNK_SIZE || 90,
|
chunkSize: process.env.CHUNK_SIZE || 90,
|
||||||
maxSize: process.env.MAX_SIZE || 5000,
|
maxSize: process.env.MAX_SIZE || 5000,
|
||||||
|
// eslint-disable-next-line eqeqeq
|
||||||
generateZips: process.env.GENERATE_ZIPS == undefined ? true : false,
|
generateZips: process.env.GENERATE_ZIPS == undefined ? true : false,
|
||||||
generatedFilenameLength: process.env.GENERATED_FILENAME_LENGTH || 12,
|
generatedFilenameLength: process.env.GENERATED_FILENAME_LENGTH || 12,
|
||||||
generatedAlbumLength: process.env.GENERATED_ALBUM_LENGTH || 6,
|
generatedAlbumLength: process.env.GENERATED_ALBUM_LENGTH || 6,
|
||||||
uploadFolder: process.env.UPLOAD_FOLDER || 'uploads',
|
|
||||||
blockedExtensions: process.env.BLOCKED_EXTENSIONS || ['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'],
|
blockedExtensions: process.env.BLOCKED_EXTENSIONS || ['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'],
|
||||||
|
// eslint-disable-next-line eqeqeq
|
||||||
publicMode: process.env.PUBLIC_MODE == undefined ? true : false,
|
publicMode: process.env.PUBLIC_MODE == undefined ? true : false,
|
||||||
|
// eslint-disable-next-line eqeqeq
|
||||||
userAccounts: process.env.USER_ACCOUNTS == undefined ? true : false,
|
userAccounts: process.env.USER_ACCOUNTS == undefined ? true : false,
|
||||||
adminAccount: process.env.ADMIN_ACCOUNT || 'admin',
|
|
||||||
adminPassword: process.env.ADMIN_PASSWORD || 'admin',
|
|
||||||
metaThemeColor: process.env.META_THEME_COLOR || '#20222b',
|
metaThemeColor: process.env.META_THEME_COLOR || '#20222b',
|
||||||
metaDescription: process.env.META_DESCRIPTION || 'Blazing fast file uploader and bunker written in node! 🚀',
|
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',
|
metaKeywords: process.env.META_KEYWORDS || 'chibisafe,lolisafe,upload,uploader,file,vue,images,ssr,file uploader,free',
|
||||||
|
@ -65,16 +62,16 @@ class Util {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static async writeConfigToDb(config, overwrite = true) {
|
static async writeConfigToDb(config) {
|
||||||
// TODO: Check that the config passes the joi schema validation
|
// TODO: Check that the config passes the joi schema validation
|
||||||
|
if (!config || !config.key || !config.key) return;
|
||||||
try {
|
try {
|
||||||
if (overwrite) {
|
config.value = JSON.stringify(config.value);
|
||||||
await db.table('settings').first().update(config);
|
await db.table('settings').insert(config);
|
||||||
} else {
|
|
||||||
await db.table('settings').insert(config);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
this.invalidateConfigCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +80,7 @@ class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
static isExtensionBlocked(extension) {
|
static isExtensionBlocked(extension) {
|
||||||
return blockedExtensions.includes(extension);
|
return this.config.blockedExtensions.includes(extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getMimeFromType(fileTypeMimeObj) {
|
static getMimeFromType(fileTypeMimeObj) {
|
||||||
|
@ -109,7 +106,7 @@ class Util {
|
||||||
static getUniqueFilename(extension) {
|
static getUniqueFilename(extension) {
|
||||||
const retry = (i = 0) => {
|
const retry = (i = 0) => {
|
||||||
const filename = randomstring.generate({
|
const filename = randomstring.generate({
|
||||||
length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
|
length: this.config.generatedFilenameLength,
|
||||||
capitalization: 'lowercase'
|
capitalization: 'lowercase'
|
||||||
}) + extension;
|
}) + extension;
|
||||||
|
|
||||||
|
@ -126,7 +123,7 @@ class Util {
|
||||||
static getUniqueAlbumIdentifier() {
|
static getUniqueAlbumIdentifier() {
|
||||||
const retry = async (i = 0) => {
|
const retry = async (i = 0) => {
|
||||||
const identifier = randomstring.generate({
|
const identifier = randomstring.generate({
|
||||||
length: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10),
|
length: this.config.generatedAlbumLength,
|
||||||
capitalization: 'lowercase'
|
capitalization: 'lowercase'
|
||||||
});
|
});
|
||||||
const exists = await db
|
const exists = await db
|
||||||
|
@ -223,7 +220,7 @@ class Util {
|
||||||
const token = req.headers.authorization.split(' ')[1];
|
const token = req.headers.authorization.split(' ')[1];
|
||||||
if (!token) return false;
|
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) {
|
if (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
return false;
|
return false;
|
||||||
|
@ -249,13 +246,7 @@ class Util {
|
||||||
zip.addLocalFile(path.join(Util.uploadPath, file));
|
zip.addLocalFile(path.join(Util.uploadPath, file));
|
||||||
}
|
}
|
||||||
zip.writeZip(
|
zip.writeZip(
|
||||||
path.join(
|
path.join(__dirname, '../../../', 'uploads', 'zips', `${album.userId}-${album.id}.zip`)
|
||||||
__dirname,
|
|
||||||
'../../../',
|
|
||||||
process.env.UPLOAD_FOLDER,
|
|
||||||
'zips',
|
|
||||||
`${album.userId}-${album.id}.zip`
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
|
|
|
@ -6,7 +6,7 @@ const path = require('path');
|
||||||
const ThumbUtil = require('./ThumbUtil');
|
const ThumbUtil = require('./ThumbUtil');
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
const files = fs.readdirSync(path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER));
|
const files = fs.readdirSync(path.join(__dirname, '../../../uploads'));
|
||||||
for (const fileName of files) {
|
for (const fileName of files) {
|
||||||
console.log(`Generating thumb for '${fileName}`);
|
console.log(`Generating thumb for '${fileName}`);
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
|
110
src/setup.js
110
src/setup.js
|
@ -1,5 +1,4 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
const randomstring = require('randomstring');
|
|
||||||
const jetpack = require('fs-jetpack');
|
const jetpack = require('fs-jetpack');
|
||||||
const qoa = require('qoa');
|
const qoa = require('qoa');
|
||||||
|
|
||||||
|
@ -16,53 +15,12 @@ async function start() {
|
||||||
const wizard = [
|
const wizard = [
|
||||||
{
|
{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
query: 'Port to run chibisafe in: (5000)',
|
query: 'Port to run chibisafe in? (default: 5000)',
|
||||||
handle: 'SERVER_PORT'
|
handle: 'SERVER_PORT'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
query: 'Full domain this instance is gonna be running on (Ex: https://chibisafe.moe):',
|
|
||||||
handle: 'DOMAIN'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
query: 'Name of the service? (Ex: chibisafe):',
|
|
||||||
handle: 'SERVICE_NAME'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
query: 'Maximum allowed upload file size in MB (Ex: 100):',
|
|
||||||
handle: 'MAX_SIZE'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
query: 'Allow users to download entire albums in ZIP format? (true)',
|
|
||||||
handle: 'GENERATE_ZIPS',
|
|
||||||
accept: 'y',
|
|
||||||
deny: 'n'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
query: 'Allow people to upload files without an account? (true)',
|
|
||||||
handle: 'PUBLIC_MODE',
|
|
||||||
accept: 'y',
|
|
||||||
deny: 'n'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
query: 'Allow people to create new accounts? (true)',
|
|
||||||
handle: 'USER_ACCOUNTS',
|
|
||||||
accept: 'y',
|
|
||||||
deny: 'n'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
query: 'Name of the admin account? (admin)',
|
|
||||||
handle: 'ADMIN_ACCOUNT'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: 'interactive',
|
type: 'interactive',
|
||||||
query: 'Which predefined database do you want to use?',
|
query: 'Which database do you want to use? (select sqlite3 if not sure)',
|
||||||
handle: 'DB_CLIENT',
|
handle: 'DB_CLIENT',
|
||||||
symbol: '>',
|
symbol: '>',
|
||||||
menu: [
|
menu: [
|
||||||
|
@ -73,22 +31,22 @@ async function start() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
query: 'Database host (Ignore if you selected sqlite3):',
|
query: 'Database host (Leave blank if you selected sqlite3):',
|
||||||
handle: 'DB_HOST'
|
handle: 'DB_HOST'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
query: 'Database user (Ignore if you selected sqlite3):',
|
query: 'Database user (Leave blank if you selected sqlite3):',
|
||||||
handle: 'DB_USER'
|
handle: 'DB_USER'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
query: 'Database password (Ignore if you selected sqlite3):',
|
query: 'Database password (Leave blank if you selected sqlite3):',
|
||||||
handle: 'DB_PASSWORD'
|
handle: 'DB_PASSWORD'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
query: 'Database name (Ignore if you selected sqlite3):',
|
query: 'Database name (Leave blank if you selected sqlite3):',
|
||||||
handle: 'DB_DATABASE'
|
handle: 'DB_DATABASE'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -97,69 +55,29 @@ async function start() {
|
||||||
let envfile = '';
|
let envfile = '';
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
_1: '# Server settings',
|
|
||||||
SERVER_PORT: response.SERVER_PORT || 5000,
|
SERVER_PORT: response.SERVER_PORT || 5000,
|
||||||
WEBSITE_PORT: 5001,
|
|
||||||
ROUTE_PREFIX: '/api',
|
|
||||||
RATE_LIMIT_WINDOW: 2,
|
|
||||||
RATE_LIMIT_MAX: 5,
|
|
||||||
SECRET: randomstring.generate(64),
|
|
||||||
|
|
||||||
_2: '# Service settings',
|
|
||||||
SERVICE_NAME: response.SERVICE_NAME || 'change-me',
|
|
||||||
DOMAIN: response.DOMAIN || `http://localhost:${response.SERVER_PORT}`,
|
|
||||||
|
|
||||||
_3: '# File related settings',
|
|
||||||
CHUNK_SIZE: 90,
|
|
||||||
MAX_SIZE: response.MAX_SIZE || 5000,
|
|
||||||
GENERATE_ZIPS: response.GENERATE_ZIPS == undefined ? true : false,
|
|
||||||
GENERATED_FILENAME_LENGTH: 12,
|
|
||||||
GENERATED_ALBUM_LENGTH: 6,
|
|
||||||
MAX_LINKS_PER_ALBUM: 5,
|
|
||||||
UPLOAD_FOLDER: 'uploads',
|
|
||||||
BLOCKED_EXTENSIONS: ['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'],
|
|
||||||
|
|
||||||
_4: '# User settings',
|
|
||||||
PUBLIC_MODE: response.PUBLIC_MODE == undefined ? true : false,
|
|
||||||
USER_ACCOUNTS: response.USER_ACCOUNTS == undefined ? true : false,
|
|
||||||
ADMIN_ACCOUNT: response.ADMIN_ACCOUNT || 'admin',
|
|
||||||
ADMIN_PASSWORD: randomstring.generate(16),
|
|
||||||
|
|
||||||
_5: '# Database connection settings',
|
|
||||||
DB_CLIENT: response.DB_CLIENT,
|
DB_CLIENT: response.DB_CLIENT,
|
||||||
DB_HOST: response.DB_HOST || null,
|
DB_HOST: response.DB_HOST || null,
|
||||||
DB_USER: response.DB_USER || null,
|
DB_USER: response.DB_USER || null,
|
||||||
DB_PASSWORD: response.DB_PASSWORD || null,
|
DB_PASSWORD: response.DB_PASSWORD || null,
|
||||||
DB_DATABASE: response.DB_DATABASE || null,
|
DB_DATABASE: response.DB_DATABASE || null
|
||||||
|
|
||||||
_6: '# Social and sharing settings',
|
|
||||||
META_THEME_COLOR: '#20222b',
|
|
||||||
META_DESCRIPTION: 'Blazing fast file uploader and bunker written in node! 🚀',
|
|
||||||
META_KEYWORDS: 'chibisafe,lolisafe,upload,uploader,file,vue,images,ssr,file uploader,free',
|
|
||||||
META_TWITTER_HANDLE: '@its_pitu'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const keys = Object.keys(defaultSettings);
|
const keys = Object.keys(defaultSettings);
|
||||||
|
|
||||||
for (const item of keys) {
|
for (const item of keys) {
|
||||||
let prefix = `${item}=`;
|
envfile += `${item}=${defaultSettings[item]}\n`;
|
||||||
if (item.startsWith('_1')) {
|
|
||||||
prefix = '';
|
|
||||||
} else if (item.startsWith('_')) {
|
|
||||||
prefix = '\n';
|
|
||||||
}
|
|
||||||
envfile += `${prefix}${defaultSettings[item]}\n`;
|
|
||||||
}
|
}
|
||||||
jetpack.write('.env', envfile);
|
jetpack.write('.env', envfile);
|
||||||
jetpack.dir('database');
|
jetpack.dir('database');
|
||||||
|
|
||||||
console.log();
|
console.log();
|
||||||
console.log('====================================================');
|
console.log('=====================================================');
|
||||||
console.log('== .env file generated successfully. ==');
|
console.log('== .env file generated successfully. ==');
|
||||||
console.log('====================================================');
|
console.log('=====================================================');
|
||||||
console.log(`== Your admin password is: ${defaultSettings.ADMIN_PASSWORD} ==`);
|
console.log(`== Both your initial user and password are 'admin' ==`);
|
||||||
console.log('== MAKE SURE TO CHANGE IT AFTER YOUR FIRST LOGIN! ==');
|
console.log('== MAKE SURE TO CHANGE IT AFTER YOUR FIRST LOGIN ==');
|
||||||
console.log('====================================================');
|
console.log('=====================================================');
|
||||||
console.log();
|
console.log();
|
||||||
setTimeout(() => {}, 1000);
|
setTimeout(() => {}, 1000);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue