chore: update process.env usage

This commit is contained in:
Pitu 2021-06-15 00:12:26 +09:00
parent 9b28e56e09
commit d3c80127ec
12 changed files with 76 additions and 162 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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.',

View File

@ -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;

View File

@ -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'
} }
}); });
} }

View File

@ -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' });

View File

@ -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' });

View File

@ -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();

View File

@ -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({

View File

@ -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);

View File

@ -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

View File

@ -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);
} }